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/1697] 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 20e85bbb5..808f8e7e3 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 @@ namespace Flow.Launcher.Plugin.Explorer.Search.WindowsIndex
///
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/1697] 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 808f8e7e3..c42a60193 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 @@ namespace Flow.Launcher.Plugin.Explorer.Search.WindowsIndex
///
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/1697] 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 dc3b3f145..7d8c195f3 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 332e0f502..1dd9fe34d 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 @@ namespace Flow.Launcher
_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 @@ namespace Flow.Launcher
}
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/1697] 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 245ab4d05..efa43000b 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 @@ namespace Flow.Launcher
DataContext = mainVM;
_viewModel = mainVM;
_settings = settings;
-
+
InitializeComponent();
InitializePosition();
animationSound.Open(new Uri(AppDomain.CurrentDomain.BaseDirectory + "Resources\\open.wav"));
@@ -60,7 +61,7 @@ namespace Flow.Launcher
{
InitializeComponent();
}
-
+
private void OnCopy(object sender, ExecutedRoutedEventArgs e)
{
if (QueryTextBox.SelectionLength == 0)
@@ -108,29 +109,29 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
}
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 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
// and always after Settings window is closed.
if (_settings.UseAnimation)
await Task.Delay(100);
-
+
if (_settings.HideWhenDeactive)
{
_viewModel.Hide();
@@ -454,7 +481,7 @@ namespace Flow.Launcher
_viewModel.Show();
}
}
-
+
public double HorizonCenter()
{
var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position);
@@ -536,9 +563,9 @@ namespace Flow.Launcher
&& 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 @@ namespace Flow.Launcher
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/1697] 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 000000000..ba0ddd6ab
--- /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 000000000..6fd6472db
--- /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 000000000..f275d129c
--- /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 3abd05f6b3a687e73fc9e6ab0f09ec2af2f6c06a Mon Sep 17 00:00:00 2001
From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Sat, 18 Nov 2023 14:58:16 +0800
Subject: [PATCH 0006/1697] Implement double pinyin
---
.../DoublePinAlphabet.cs | 193 ++++++++++++++++++
.../UserSettings/Settings.cs | 2 +
2 files changed, 195 insertions(+)
create mode 100644 Flow.Launcher.Infrastructure/DoublePinAlphabet.cs
diff --git a/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs b/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs
new file mode 100644
index 000000000..607582097
--- /dev/null
+++ b/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs
@@ -0,0 +1,193 @@
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
+using System.Text;
+using Flow.Launcher.Infrastructure.UserSettings;
+using ToolGood.Words.Pinyin;
+
+namespace Flow.Launcher.Infrastructure
+{
+ public class DoublePinAlphabet : IAlphabet
+ {
+ private ConcurrentDictionary _doublePinCache =
+ new ConcurrentDictionary();
+
+ private Settings _settings;
+
+ public void Initialize([NotNull] Settings settings)
+ {
+ _settings = settings ?? throw new ArgumentNullException(nameof(settings));
+ }
+
+ public bool CanBeTranslated(string stringToTranslate)
+ {
+ return WordsHelper.HasChinese(stringToTranslate);
+ }
+
+ public (string translation, TranslationMapping map) Translate(string content)
+ {
+ if (_settings.ShouldUseDoublePin)
+ {
+ if (!_doublePinCache.ContainsKey(content))
+ {
+ return BuildCacheFromContent(content);
+ }
+ else
+ {
+ return _doublePinCache[content];
+ }
+ }
+ return (content, null);
+ }
+
+ private (string translation, TranslationMapping map) BuildCacheFromContent(string content)
+ {
+ if (WordsHelper.HasChinese(content))
+ {
+ var resultList = WordsHelper.GetPinyinList(content).Select(ToDoublePin).ToArray();
+ StringBuilder resultBuilder = new StringBuilder();
+ TranslationMapping map = new TranslationMapping();
+
+ bool pre = false;
+
+ for (int i = 0; i < resultList.Length; i++)
+ {
+ if (content[i] >= 0x3400 && content[i] <= 0x9FD5)
+ {
+ map.AddNewIndex(i, resultBuilder.Length, resultList[i].Length + 1);
+ resultBuilder.Append(' ');
+ resultBuilder.Append(resultList[i]);
+ pre = true;
+ }
+ else
+ {
+ if (pre)
+ {
+ pre = false;
+ resultBuilder.Append(' ');
+ }
+
+ resultBuilder.Append(resultList[i]);
+ }
+ }
+
+ map.endConstruct();
+
+ var key = resultBuilder.ToString();
+ map.setKey(key);
+
+ return _doublePinCache[content] = (key, map);
+ }
+ else
+ {
+ return (content, null);
+ }
+ }
+
+ private static readonly ReadOnlyDictionary special = new(new Dictionary(){
+ {"a", "aa"},
+ {"ai", "ai"},
+ {"an", "an"},
+ {"ang", "ah"},
+ {"ao", "ao"},
+ {"e", "ee"},
+ {"ei", "ei"},
+ {"en", "en"},
+ {"er", "er"},
+ {"o", "oo"},
+ {"ou", "ou"}
+ });
+
+
+ private static readonly ReadOnlyDictionary first = new(new Dictionary(){
+ {"ch", "i"},
+ {"sh", "u"},
+ {"zh", "v"}
+ });
+
+
+ private static readonly ReadOnlyDictionary second = new(new Dictionary()
+ {
+ {"ua", "x"},
+ {"ei", "w"},
+ {"e", "e"},
+ {"ou", "z"},
+ {"iu", "q"},
+ {"ve", "t"},
+ {"ue", "t"},
+ {"u", "u"},
+ {"i", "i"},
+ {"o", "o"},
+ {"uo", "o"},
+ {"ie", "p"},
+ {"a", "a"},
+ {"ong", "s"},
+ {"iong", "s"},
+ {"ai", "d"},
+ {"ing", "k"},
+ {"uai", "k"},
+ {"ang", "h"},
+ {"uan", "r"},
+ {"an", "j"},
+ {"en", "f"},
+ {"ia", "x"},
+ {"iang", "l"},
+ {"uang", "l"},
+ {"eng", "g"},
+ {"in", "b"},
+ {"ao", "c"},
+ {"v", "v"},
+ {"ui", "v"},
+ {"un", "y"},
+ {"iao", "n"},
+ {"ian", "m"}
+ });
+
+ private static string ToDoublePin(string fullPinyin)
+ {
+ // Assuming s is valid
+ StringBuilder doublePin = new StringBuilder();
+
+ if (fullPinyin.Length <= 3 && (fullPinyin[0] == 'a' || fullPinyin[0] == 'e' || fullPinyin[0] == 'o'))
+ {
+ if (special.ContainsKey(fullPinyin))
+ {
+ return special[fullPinyin];
+ }
+ }
+
+ // zh, ch, sh
+ if (fullPinyin.Length >= 2 && first.ContainsKey(fullPinyin[..2]))
+ {
+ doublePin.Append(first[fullPinyin[..2]]);
+
+ if (second.TryGetValue(fullPinyin[2..], out string tmp))
+ {
+ doublePin.Append(tmp);
+ }
+ else
+ {
+ doublePin.Append(fullPinyin[2..]);
+ }
+ }
+ else
+ {
+ doublePin.Append(fullPinyin[0]);
+
+ if (second.TryGetValue(fullPinyin[1..], out string tmp))
+ {
+ doublePin.Append(tmp);
+ }
+ else
+ {
+ doublePin.Append(fullPinyin[1..]);
+ }
+ }
+
+ return doublePin.ToString();
+ }
+ }
+}
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index 458846665..8d94cdba5 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -185,6 +185,8 @@ namespace Flow.Launcher.Infrastructure.UserSettings
/// when false Alphabet static service will always return empty results
///
public bool ShouldUsePinyin { get; set; } = false;
+
+ public bool ShouldUseDoublePin { get; set; } = false;
public bool AlwaysPreview { get; set; } = false;
public bool AlwaysStartEn { get; set; } = false;
From fb6635344b8e5ecae06aadd31a3b112471b48ae2 Mon Sep 17 00:00:00 2001
From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Sat, 18 Nov 2023 14:58:23 +0800
Subject: [PATCH 0007/1697] Test double pinyin
---
Flow.Launcher/App.xaml.cs | 2 +-
Flow.Launcher/PublicAPIInstance.cs | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 765a1a559..d74ea62fb 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -30,7 +30,7 @@ namespace Flow.Launcher
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 readonly DoublePinAlphabet _alphabet = new DoublePinAlphabet();
private StringMatcher _stringMatcher;
[STAThread]
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index b49bf39d3..952ce0edb 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -32,11 +32,11 @@ namespace Flow.Launcher
{
private readonly SettingWindowViewModel _settingsVM;
private readonly MainViewModel _mainVM;
- private readonly PinyinAlphabet _alphabet;
+ private readonly DoublePinAlphabet _alphabet;
#region Constructor
- public PublicAPIInstance(SettingWindowViewModel settingsVM, MainViewModel mainVM, PinyinAlphabet alphabet)
+ public PublicAPIInstance(SettingWindowViewModel settingsVM, MainViewModel mainVM, DoublePinAlphabet alphabet)
{
_settingsVM = settingsVM;
_mainVM = mainVM;
From f6ae71a99f838b2237c14c62c6daff5e97e6eec0 Mon Sep 17 00:00:00 2001
From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Sat, 18 Nov 2023 20:24:13 +0800
Subject: [PATCH 0008/1697] Only convert to double pinyin when meeting Chinese
---
Flow.Launcher.Infrastructure/DoublePinAlphabet.cs | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs b/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs
index 607582097..e09046410 100644
--- a/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs
+++ b/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs
@@ -47,7 +47,7 @@ namespace Flow.Launcher.Infrastructure
{
if (WordsHelper.HasChinese(content))
{
- var resultList = WordsHelper.GetPinyinList(content).Select(ToDoublePin).ToArray();
+ var resultList = WordsHelper.GetPinyinList(content);
StringBuilder resultBuilder = new StringBuilder();
TranslationMapping map = new TranslationMapping();
@@ -57,9 +57,10 @@ namespace Flow.Launcher.Infrastructure
{
if (content[i] >= 0x3400 && content[i] <= 0x9FD5)
{
- map.AddNewIndex(i, resultBuilder.Length, resultList[i].Length + 1);
+ string dp = ToDoublePin(resultList[i].ToLower());
+ map.AddNewIndex(i, resultBuilder.Length, dp.Length + 1);
resultBuilder.Append(' ');
- resultBuilder.Append(resultList[i]);
+ resultBuilder.Append(dp);
pre = true;
}
else
From e5285b19921ae2cc49b6f55ebe5772a77f05cd54 Mon Sep 17 00:00:00 2001
From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Sun, 19 Nov 2023 12:30:17 +0800
Subject: [PATCH 0009/1697] Temp: compatibility with full pinyin option
---
Flow.Launcher.Infrastructure/DoublePinAlphabet.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs b/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs
index e09046410..e6930ad93 100644
--- a/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs
+++ b/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs
@@ -29,7 +29,7 @@ namespace Flow.Launcher.Infrastructure
public (string translation, TranslationMapping map) Translate(string content)
{
- if (_settings.ShouldUseDoublePin)
+ if (_settings.ShouldUsePinyin)
{
if (!_doublePinCache.ContainsKey(content))
{
@@ -57,7 +57,7 @@ namespace Flow.Launcher.Infrastructure
{
if (content[i] >= 0x3400 && content[i] <= 0x9FD5)
{
- string dp = ToDoublePin(resultList[i].ToLower());
+ string dp = _settings.ShouldUseDoublePin ? resultList[i] : ToDoublePin(resultList[i].ToLower());
map.AddNewIndex(i, resultBuilder.Length, dp.Length + 1);
resultBuilder.Append(' ');
resultBuilder.Append(dp);
From 99ff3b2ec5c9a4d8b4f136735a866f52914c246e Mon Sep 17 00:00:00 2001
From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Mon, 20 Nov 2023 22:49:39 +0800
Subject: [PATCH 0010/1697] Fix wrong condition
---
Flow.Launcher.Infrastructure/DoublePinAlphabet.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs b/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs
index e6930ad93..a1eb788d7 100644
--- a/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs
+++ b/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs
@@ -57,7 +57,7 @@ namespace Flow.Launcher.Infrastructure
{
if (content[i] >= 0x3400 && content[i] <= 0x9FD5)
{
- string dp = _settings.ShouldUseDoublePin ? resultList[i] : ToDoublePin(resultList[i].ToLower());
+ string dp = _settings.ShouldUseDoublePin ? ToDoublePin(resultList[i].ToLower()) : resultList[i];
map.AddNewIndex(i, resultBuilder.Length, dp.Length + 1);
resultBuilder.Append(' ');
resultBuilder.Append(dp);
From 46d49d8fdf373e020481b111cbd23bf8ee09538d Mon Sep 17 00:00:00 2001
From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Sat, 25 May 2024 15:02:37 +0800
Subject: [PATCH 0011/1697] Only translate when string is double pinyin
---
Flow.Launcher.Infrastructure/DoublePinAlphabet.cs | 4 ++--
Flow.Launcher.Infrastructure/PinyinAlphabet.cs | 4 ++--
Flow.Launcher.Infrastructure/StringMatcher.cs | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs b/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs
index a1eb788d7..945f47a56 100644
--- a/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs
+++ b/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs
@@ -22,9 +22,9 @@ namespace Flow.Launcher.Infrastructure
_settings = settings ?? throw new ArgumentNullException(nameof(settings));
}
- public bool CanBeTranslated(string stringToTranslate)
+ public bool ShouldTranslate(string stringToTranslate)
{
- return WordsHelper.HasChinese(stringToTranslate);
+ return stringToTranslate.Length % 2 == 0 && !WordsHelper.HasChinese(stringToTranslate);
}
public (string translation, TranslationMapping map) Translate(string content)
diff --git a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
index 7d7235968..961af1d32 100644
--- a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
+++ b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
@@ -119,7 +119,7 @@ namespace Flow.Launcher.Infrastructure
///
/// String to translate.
///
- public bool CanBeTranslated(string stringToTranslate);
+ public bool ShouldTranslate(string stringToTranslate);
}
public class PinyinAlphabet : IAlphabet
@@ -134,7 +134,7 @@ namespace Flow.Launcher.Infrastructure
_settings = settings ?? throw new ArgumentNullException(nameof(settings));
}
- public bool CanBeTranslated(string stringToTranslate)
+ public bool ShouldTranslate(string stringToTranslate)
{
return WordsHelper.HasChinese(stringToTranslate);
}
diff --git a/Flow.Launcher.Infrastructure/StringMatcher.cs b/Flow.Launcher.Infrastructure/StringMatcher.cs
index bd5dbdda9..4929e4cd2 100644
--- a/Flow.Launcher.Infrastructure/StringMatcher.cs
+++ b/Flow.Launcher.Infrastructure/StringMatcher.cs
@@ -61,7 +61,7 @@ namespace Flow.Launcher.Infrastructure
query = query.Trim();
TranslationMapping translationMapping = null;
- if (_alphabet is not null && !_alphabet.CanBeTranslated(query))
+ if (_alphabet is not null && _alphabet.ShouldTranslate(query))
{
// We assume that if a query can be translated (containing characters of a language, like Chinese)
// it actually means user doesn't want it to be translated to English letters.
From b1cb852673005e955b1d4bd0bb2ed692e44308c9 Mon Sep 17 00:00:00 2001
From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Sun, 2 Jun 2024 14:18:57 +0800
Subject: [PATCH 0012/1697] Extract classes
---
Flow.Launcher.Infrastructure/IAlphabet.cs | 22 ++++
.../PinyinAlphabet.cs | 113 ------------------
.../TranslationMapping.cs | 99 +++++++++++++++
3 files changed, 121 insertions(+), 113 deletions(-)
create mode 100644 Flow.Launcher.Infrastructure/IAlphabet.cs
create mode 100644 Flow.Launcher.Infrastructure/TranslationMapping.cs
diff --git a/Flow.Launcher.Infrastructure/IAlphabet.cs b/Flow.Launcher.Infrastructure/IAlphabet.cs
new file mode 100644
index 000000000..e79ec0c6d
--- /dev/null
+++ b/Flow.Launcher.Infrastructure/IAlphabet.cs
@@ -0,0 +1,22 @@
+namespace Flow.Launcher.Infrastructure
+{
+ ///
+ /// Translate a language to English letters using a given rule.
+ ///
+ public interface IAlphabet
+ {
+ ///
+ /// Translate a string to English letters, using a given rule.
+ ///
+ /// String to translate.
+ ///
+ public (string translation, TranslationMapping map) Translate(string stringToTranslate);
+
+ ///
+ /// Determine if a string can be translated to English letter with this Alphabet.
+ ///
+ /// String to translate.
+ ///
+ public bool ShouldTranslate(string stringToTranslate);
+ }
+}
diff --git a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
index 961af1d32..d98d823d7 100644
--- a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
+++ b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
@@ -9,119 +9,6 @@ using ToolGood.Words.Pinyin;
namespace Flow.Launcher.Infrastructure
{
- public class TranslationMapping
- {
- private bool constructed;
-
- private List originalIndexs = new List();
- private List translatedIndexs = new List();
- private int translatedLength = 0;
-
- public string key { get; private set; }
-
- public void setKey(string key)
- {
- this.key = key;
- }
-
- public void AddNewIndex(int originalIndex, int translatedIndex, int length)
- {
- if (constructed)
- throw new InvalidOperationException("Mapping shouldn't be changed after constructed");
-
- originalIndexs.Add(originalIndex);
- translatedIndexs.Add(translatedIndex);
- translatedIndexs.Add(translatedIndex + length);
- translatedLength += length - 1;
- }
-
- public int MapToOriginalIndex(int translatedIndex)
- {
- if (translatedIndex > translatedIndexs.Last())
- return translatedIndex - translatedLength - 1;
-
- int lowerBound = 0;
- int upperBound = originalIndexs.Count - 1;
-
- int count = 0;
-
- // Corner case handle
- if (translatedIndex < translatedIndexs[0])
- return translatedIndex;
- if (translatedIndex > translatedIndexs.Last())
- {
- int indexDef = 0;
- for (int k = 0; k < originalIndexs.Count; k++)
- {
- indexDef += translatedIndexs[k * 2 + 1] - translatedIndexs[k * 2];
- }
-
- return translatedIndex - indexDef - 1;
- }
-
- // Binary Search with Range
- for (int i = originalIndexs.Count / 2;; count++)
- {
- if (translatedIndex < translatedIndexs[i * 2])
- {
- // move to lower middle
- upperBound = i;
- i = (i + lowerBound) / 2;
- }
- else if (translatedIndex > translatedIndexs[i * 2 + 1] - 1)
- {
- lowerBound = i;
- // move to upper middle
- // due to floor of integer division, move one up on corner case
- i = (i + upperBound + 1) / 2;
- }
- else
- return originalIndexs[i];
-
- if (upperBound - lowerBound <= 1 &&
- translatedIndex > translatedIndexs[lowerBound * 2 + 1] &&
- translatedIndex < translatedIndexs[upperBound * 2])
- {
- int indexDef = 0;
-
- for (int j = 0; j < upperBound; j++)
- {
- indexDef += translatedIndexs[j * 2 + 1] - translatedIndexs[j * 2];
- }
-
- return translatedIndex - indexDef - 1;
- }
- }
- }
-
- public void endConstruct()
- {
- if (constructed)
- throw new InvalidOperationException("Mapping has already been constructed");
- constructed = true;
- }
- }
-
- ///
- /// Translate a language to English letters using a given rule.
- ///
- public interface IAlphabet
- {
- ///
- /// Translate a string to English letters, using a given rule.
- ///
- /// String to translate.
- ///
- public (string translation, TranslationMapping map) Translate(string stringToTranslate);
-
- ///
- /// Determine if a string can be translated to English letter with this Alphabet.
- ///
- /// String to translate.
- ///
- public bool ShouldTranslate(string stringToTranslate);
- }
-
public class PinyinAlphabet : IAlphabet
{
private ConcurrentDictionary _pinyinCache =
diff --git a/Flow.Launcher.Infrastructure/TranslationMapping.cs b/Flow.Launcher.Infrastructure/TranslationMapping.cs
new file mode 100644
index 000000000..f288c816a
--- /dev/null
+++ b/Flow.Launcher.Infrastructure/TranslationMapping.cs
@@ -0,0 +1,99 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Flow.Launcher.Infrastructure
+{
+ public class TranslationMapping
+ {
+ private bool constructed;
+
+ private List originalIndexs = new List();
+ private List translatedIndexs = new List();
+ private int translatedLength = 0;
+
+ public string key { get; private set; }
+
+ public void setKey(string key)
+ {
+ this.key = key;
+ }
+
+ public void AddNewIndex(int originalIndex, int translatedIndex, int length)
+ {
+ if (constructed)
+ throw new InvalidOperationException("Mapping shouldn't be changed after constructed");
+
+ originalIndexs.Add(originalIndex);
+ translatedIndexs.Add(translatedIndex);
+ translatedIndexs.Add(translatedIndex + length);
+ translatedLength += length - 1;
+ }
+
+ public int MapToOriginalIndex(int translatedIndex)
+ {
+ if (translatedIndex > translatedIndexs.Last())
+ return translatedIndex - translatedLength - 1;
+
+ int lowerBound = 0;
+ int upperBound = originalIndexs.Count - 1;
+
+ int count = 0;
+
+ // Corner case handle
+ if (translatedIndex < translatedIndexs[0])
+ return translatedIndex;
+ if (translatedIndex > translatedIndexs.Last())
+ {
+ int indexDef = 0;
+ for (int k = 0; k < originalIndexs.Count; k++)
+ {
+ indexDef += translatedIndexs[k * 2 + 1] - translatedIndexs[k * 2];
+ }
+
+ return translatedIndex - indexDef - 1;
+ }
+
+ // Binary Search with Range
+ for (int i = originalIndexs.Count / 2;; count++)
+ {
+ if (translatedIndex < translatedIndexs[i * 2])
+ {
+ // move to lower middle
+ upperBound = i;
+ i = (i + lowerBound) / 2;
+ }
+ else if (translatedIndex > translatedIndexs[i * 2 + 1] - 1)
+ {
+ lowerBound = i;
+ // move to upper middle
+ // due to floor of integer division, move one up on corner case
+ i = (i + upperBound + 1) / 2;
+ }
+ else
+ return originalIndexs[i];
+
+ if (upperBound - lowerBound <= 1 &&
+ translatedIndex > translatedIndexs[lowerBound * 2 + 1] &&
+ translatedIndex < translatedIndexs[upperBound * 2])
+ {
+ int indexDef = 0;
+
+ for (int j = 0; j < upperBound; j++)
+ {
+ indexDef += translatedIndexs[j * 2 + 1] - translatedIndexs[j * 2];
+ }
+
+ return translatedIndex - indexDef - 1;
+ }
+ }
+ }
+
+ public void endConstruct()
+ {
+ if (constructed)
+ throw new InvalidOperationException("Mapping has already been constructed");
+ constructed = true;
+ }
+ }
+}
From 6807afbe6d753eed6984e1b1ab6019e2864767cd Mon Sep 17 00:00:00 2001
From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Sun, 2 Jun 2024 14:03:00 +0800
Subject: [PATCH 0013/1697] Remove unused alphabet arg in PublicAPIInstance
---
Flow.Launcher/App.xaml.cs | 2 +-
Flow.Launcher/PublicAPIInstance.cs | 4 +---
2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index d74ea62fb..560bb052b 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -74,7 +74,7 @@ namespace Flow.Launcher
PluginManager.LoadPlugins(_settings.PluginSettings);
_mainVM = new MainViewModel(_settings);
- API = new PublicAPIInstance(_settingsVM, _mainVM, _alphabet);
+ API = new PublicAPIInstance(_settingsVM, _mainVM);
Http.API = API;
Http.Proxy = _settings.Proxy;
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 952ce0edb..e14d692cd 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -32,15 +32,13 @@ namespace Flow.Launcher
{
private readonly SettingWindowViewModel _settingsVM;
private readonly MainViewModel _mainVM;
- private readonly DoublePinAlphabet _alphabet;
#region Constructor
- public PublicAPIInstance(SettingWindowViewModel settingsVM, MainViewModel mainVM, DoublePinAlphabet alphabet)
+ public PublicAPIInstance(SettingWindowViewModel settingsVM, MainViewModel mainVM)
{
_settingsVM = settingsVM;
_mainVM = mainVM;
- _alphabet = alphabet;
GlobalHotkey.hookedKeyboardCallback = KListener_hookedKeyboardCallback;
WebRequest.RegisterPrefix("data", new DataWebRequestFactory());
}
From a2efa11699fed4b3aac21bdff26555ce57b274aa Mon Sep 17 00:00:00 2001
From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Sun, 2 Jun 2024 14:19:27 +0800
Subject: [PATCH 0014/1697] Merge DoublePinAlphabet logic
---
.../DoublePinAlphabet.cs | 194 ------------------
.../PinyinAlphabet.cs | 127 +++++++++++-
.../UserSettings/Settings.cs | 3 +-
Flow.Launcher/App.xaml.cs | 2 +-
4 files changed, 121 insertions(+), 205 deletions(-)
delete mode 100644 Flow.Launcher.Infrastructure/DoublePinAlphabet.cs
diff --git a/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs b/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs
deleted file mode 100644
index 945f47a56..000000000
--- a/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs
+++ /dev/null
@@ -1,194 +0,0 @@
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Diagnostics.CodeAnalysis;
-using System.Linq;
-using System.Text;
-using Flow.Launcher.Infrastructure.UserSettings;
-using ToolGood.Words.Pinyin;
-
-namespace Flow.Launcher.Infrastructure
-{
- public class DoublePinAlphabet : IAlphabet
- {
- private ConcurrentDictionary _doublePinCache =
- new ConcurrentDictionary();
-
- private Settings _settings;
-
- public void Initialize([NotNull] Settings settings)
- {
- _settings = settings ?? throw new ArgumentNullException(nameof(settings));
- }
-
- public bool ShouldTranslate(string stringToTranslate)
- {
- return stringToTranslate.Length % 2 == 0 && !WordsHelper.HasChinese(stringToTranslate);
- }
-
- public (string translation, TranslationMapping map) Translate(string content)
- {
- if (_settings.ShouldUsePinyin)
- {
- if (!_doublePinCache.ContainsKey(content))
- {
- return BuildCacheFromContent(content);
- }
- else
- {
- return _doublePinCache[content];
- }
- }
- return (content, null);
- }
-
- private (string translation, TranslationMapping map) BuildCacheFromContent(string content)
- {
- if (WordsHelper.HasChinese(content))
- {
- var resultList = WordsHelper.GetPinyinList(content);
- StringBuilder resultBuilder = new StringBuilder();
- TranslationMapping map = new TranslationMapping();
-
- bool pre = false;
-
- for (int i = 0; i < resultList.Length; i++)
- {
- if (content[i] >= 0x3400 && content[i] <= 0x9FD5)
- {
- string dp = _settings.ShouldUseDoublePin ? ToDoublePin(resultList[i].ToLower()) : resultList[i];
- map.AddNewIndex(i, resultBuilder.Length, dp.Length + 1);
- resultBuilder.Append(' ');
- resultBuilder.Append(dp);
- pre = true;
- }
- else
- {
- if (pre)
- {
- pre = false;
- resultBuilder.Append(' ');
- }
-
- resultBuilder.Append(resultList[i]);
- }
- }
-
- map.endConstruct();
-
- var key = resultBuilder.ToString();
- map.setKey(key);
-
- return _doublePinCache[content] = (key, map);
- }
- else
- {
- return (content, null);
- }
- }
-
- private static readonly ReadOnlyDictionary special = new(new Dictionary(){
- {"a", "aa"},
- {"ai", "ai"},
- {"an", "an"},
- {"ang", "ah"},
- {"ao", "ao"},
- {"e", "ee"},
- {"ei", "ei"},
- {"en", "en"},
- {"er", "er"},
- {"o", "oo"},
- {"ou", "ou"}
- });
-
-
- private static readonly ReadOnlyDictionary first = new(new Dictionary(){
- {"ch", "i"},
- {"sh", "u"},
- {"zh", "v"}
- });
-
-
- private static readonly ReadOnlyDictionary second = new(new Dictionary()
- {
- {"ua", "x"},
- {"ei", "w"},
- {"e", "e"},
- {"ou", "z"},
- {"iu", "q"},
- {"ve", "t"},
- {"ue", "t"},
- {"u", "u"},
- {"i", "i"},
- {"o", "o"},
- {"uo", "o"},
- {"ie", "p"},
- {"a", "a"},
- {"ong", "s"},
- {"iong", "s"},
- {"ai", "d"},
- {"ing", "k"},
- {"uai", "k"},
- {"ang", "h"},
- {"uan", "r"},
- {"an", "j"},
- {"en", "f"},
- {"ia", "x"},
- {"iang", "l"},
- {"uang", "l"},
- {"eng", "g"},
- {"in", "b"},
- {"ao", "c"},
- {"v", "v"},
- {"ui", "v"},
- {"un", "y"},
- {"iao", "n"},
- {"ian", "m"}
- });
-
- private static string ToDoublePin(string fullPinyin)
- {
- // Assuming s is valid
- StringBuilder doublePin = new StringBuilder();
-
- if (fullPinyin.Length <= 3 && (fullPinyin[0] == 'a' || fullPinyin[0] == 'e' || fullPinyin[0] == 'o'))
- {
- if (special.ContainsKey(fullPinyin))
- {
- return special[fullPinyin];
- }
- }
-
- // zh, ch, sh
- if (fullPinyin.Length >= 2 && first.ContainsKey(fullPinyin[..2]))
- {
- doublePin.Append(first[fullPinyin[..2]]);
-
- if (second.TryGetValue(fullPinyin[2..], out string tmp))
- {
- doublePin.Append(tmp);
- }
- else
- {
- doublePin.Append(fullPinyin[2..]);
- }
- }
- else
- {
- doublePin.Append(fullPinyin[0]);
-
- if (second.TryGetValue(fullPinyin[1..], out string tmp))
- {
- doublePin.Append(tmp);
- }
- else
- {
- doublePin.Append(fullPinyin[1..]);
- }
- }
-
- return doublePin.ToString();
- }
- }
-}
diff --git a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
index d98d823d7..37e4f93d2 100644
--- a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
+++ b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
@@ -1,18 +1,18 @@
using System;
using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Linq;
using System.Text;
using JetBrains.Annotations;
using Flow.Launcher.Infrastructure.UserSettings;
using ToolGood.Words.Pinyin;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
namespace Flow.Launcher.Infrastructure
{
public class PinyinAlphabet : IAlphabet
{
- private ConcurrentDictionary _pinyinCache =
- new ConcurrentDictionary();
+ private readonly ConcurrentDictionary _pinyinCache =
+ new();
private Settings _settings;
@@ -23,20 +23,22 @@ namespace Flow.Launcher.Infrastructure
public bool ShouldTranslate(string stringToTranslate)
{
- return WordsHelper.HasChinese(stringToTranslate);
+ return _settings.UseDoublePinyin ?
+ (WordsHelper.HasChinese(stringToTranslate) && stringToTranslate.Length % 2 == 0) :
+ WordsHelper.HasChinese(stringToTranslate);
}
public (string translation, TranslationMapping map) Translate(string content)
{
if (_settings.ShouldUsePinyin)
{
- if (!_pinyinCache.ContainsKey(content))
+ if (!_pinyinCache.TryGetValue(content, out var value))
{
return BuildCacheFromContent(content);
}
else
{
- return _pinyinCache[content];
+ return value;
}
}
return (content, null);
@@ -57,9 +59,10 @@ namespace Flow.Launcher.Infrastructure
{
if (content[i] >= 0x3400 && content[i] <= 0x9FD5)
{
- map.AddNewIndex(i, resultBuilder.Length, resultList[i].Length + 1);
+ string dp = _settings.UseDoublePinyin ? ToDoublePin(resultList[i].ToLower()) : resultList[i];
+ map.AddNewIndex(i, resultBuilder.Length, dp.Length + 1);
resultBuilder.Append(' ');
- resultBuilder.Append(resultList[i]);
+ resultBuilder.Append(dp);
pre = true;
}
else
@@ -86,5 +89,111 @@ namespace Flow.Launcher.Infrastructure
return (content, null);
}
}
+
+ #region Double Pinyin
+
+ private static readonly ReadOnlyDictionary special = new(new Dictionary(){
+ {"a", "aa"},
+ {"ai", "ai"},
+ {"an", "an"},
+ {"ang", "ah"},
+ {"ao", "ao"},
+ {"e", "ee"},
+ {"ei", "ei"},
+ {"en", "en"},
+ {"er", "er"},
+ {"o", "oo"},
+ {"ou", "ou"}
+ });
+
+
+ private static readonly ReadOnlyDictionary first = new(new Dictionary(){
+ {"ch", "i"},
+ {"sh", "u"},
+ {"zh", "v"}
+ });
+
+
+ private static readonly ReadOnlyDictionary second = new(new Dictionary()
+ {
+ {"ua", "x"},
+ {"ei", "w"},
+ {"e", "e"},
+ {"ou", "z"},
+ {"iu", "q"},
+ {"ve", "t"},
+ {"ue", "t"},
+ {"u", "u"},
+ {"i", "i"},
+ {"o", "o"},
+ {"uo", "o"},
+ {"ie", "p"},
+ {"a", "a"},
+ {"ong", "s"},
+ {"iong", "s"},
+ {"ai", "d"},
+ {"ing", "k"},
+ {"uai", "k"},
+ {"ang", "h"},
+ {"uan", "r"},
+ {"an", "j"},
+ {"en", "f"},
+ {"ia", "x"},
+ {"iang", "l"},
+ {"uang", "l"},
+ {"eng", "g"},
+ {"in", "b"},
+ {"ao", "c"},
+ {"v", "v"},
+ {"ui", "v"},
+ {"un", "y"},
+ {"iao", "n"},
+ {"ian", "m"}
+ });
+
+ private static string ToDoublePin(string fullPinyin)
+ {
+ // Assuming s is valid
+ StringBuilder doublePin = new StringBuilder();
+
+ if (fullPinyin.Length <= 3 && (fullPinyin[0] == 'a' || fullPinyin[0] == 'e' || fullPinyin[0] == 'o'))
+ {
+ if (special.TryGetValue(fullPinyin, out var value))
+ {
+ return value;
+ }
+ }
+
+ // zh, ch, sh
+ if (fullPinyin.Length >= 2 && first.ContainsKey(fullPinyin[..2]))
+ {
+ doublePin.Append(first[fullPinyin[..2]]);
+
+ if (second.TryGetValue(fullPinyin[2..], out string tmp))
+ {
+ doublePin.Append(tmp);
+ }
+ else
+ {
+ doublePin.Append(fullPinyin[2..]);
+ }
+ }
+ else
+ {
+ doublePin.Append(fullPinyin[0]);
+
+ if (second.TryGetValue(fullPinyin[1..], out string tmp))
+ {
+ doublePin.Append(tmp);
+ }
+ else
+ {
+ doublePin.Append(fullPinyin[1..]);
+ }
+ }
+
+ return doublePin.ToString();
+ }
+ #endregion
}
}
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index 8d94cdba5..e79c3f52d 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -186,7 +186,8 @@ namespace Flow.Launcher.Infrastructure.UserSettings
///
public bool ShouldUsePinyin { get; set; } = false;
- public bool ShouldUseDoublePin { get; set; } = false;
+ public bool UseDoublePinyin { get; set; } = false;
+
public bool AlwaysPreview { get; set; } = false;
public bool AlwaysStartEn { get; set; } = false;
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 560bb052b..83870837a 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -30,7 +30,7 @@ namespace Flow.Launcher
private SettingWindowViewModel _settingsVM;
private readonly Updater _updater = new Updater(Flow.Launcher.Properties.Settings.Default.GithubRepo);
private readonly Portable _portable = new Portable();
- private readonly DoublePinAlphabet _alphabet = new DoublePinAlphabet();
+ private readonly PinyinAlphabet _alphabet = new PinyinAlphabet();
private StringMatcher _stringMatcher;
[STAThread]
From 12c4e37a95df44fc968a6459e7a3cbf6de4063e6 Mon Sep 17 00:00:00 2001
From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Sun, 2 Jun 2024 14:33:49 +0800
Subject: [PATCH 0015/1697] Developing
---
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 e79c3f52d..30e3b77be 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -186,7 +186,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
///
public bool ShouldUsePinyin { get; set; } = false;
- public bool UseDoublePinyin { get; set; } = false;
+ public bool UseDoublePinyin { get; set; } = true; //For developing
public bool AlwaysPreview { get; set; } = false;
public bool AlwaysStartEn { get; set; } = false;
From f673000d67e4ff1180e6d2856bf85f1640433a7c Mon Sep 17 00:00:00 2001
From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Sun, 2 Jun 2024 14:37:15 +0800
Subject: [PATCH 0016/1697] Fix ShouldTranslate()
---
Flow.Launcher.Infrastructure/PinyinAlphabet.cs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
index 37e4f93d2..b48a61090 100644
--- a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
+++ b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
@@ -23,9 +23,9 @@ namespace Flow.Launcher.Infrastructure
public bool ShouldTranslate(string stringToTranslate)
{
- return _settings.UseDoublePinyin ?
- (WordsHelper.HasChinese(stringToTranslate) && stringToTranslate.Length % 2 == 0) :
- WordsHelper.HasChinese(stringToTranslate);
+ return _settings.UseDoublePinyin ?
+ (!WordsHelper.HasChinese(stringToTranslate) && stringToTranslate.Length % 2 == 0) :
+ !WordsHelper.HasChinese(stringToTranslate);
}
public (string translation, TranslationMapping map) Translate(string content)
From b10a6e19df5afcbd13ca612f6e6952f19a3b9dde Mon Sep 17 00:00:00 2001
From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Sun, 2 Jun 2024 15:18:24 +0800
Subject: [PATCH 0017/1697] Capitalize first letter
---
.../PinyinAlphabet.cs | 104 +++++++++---------
1 file changed, 51 insertions(+), 53 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
index b48a61090..cbec7feae 100644
--- a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
+++ b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
@@ -46,71 +46,69 @@ namespace Flow.Launcher.Infrastructure
private (string translation, TranslationMapping map) BuildCacheFromContent(string content)
{
- if (WordsHelper.HasChinese(content))
- {
- var resultList = WordsHelper.GetPinyinList(content);
-
- StringBuilder resultBuilder = new StringBuilder();
- TranslationMapping map = new TranslationMapping();
-
- bool pre = false;
-
- for (int i = 0; i < resultList.Length; i++)
- {
- if (content[i] >= 0x3400 && content[i] <= 0x9FD5)
- {
- string dp = _settings.UseDoublePinyin ? ToDoublePin(resultList[i].ToLower()) : resultList[i];
- map.AddNewIndex(i, resultBuilder.Length, dp.Length + 1);
- resultBuilder.Append(' ');
- resultBuilder.Append(dp);
- pre = true;
- }
- else
- {
- if (pre)
- {
- pre = false;
- resultBuilder.Append(' ');
- }
-
- resultBuilder.Append(resultList[i]);
- }
- }
-
- map.endConstruct();
-
- var key = resultBuilder.ToString();
- map.setKey(key);
-
- return _pinyinCache[content] = (key, map);
- }
- else
+ if (!WordsHelper.HasChinese(content))
{
return (content, null);
}
+
+ var resultList = WordsHelper.GetPinyinList(content);
+
+ StringBuilder resultBuilder = new StringBuilder();
+ TranslationMapping map = new TranslationMapping();
+
+ bool pre = false;
+
+ for (int i = 0; i < resultList.Length; i++)
+ {
+ if (content[i] >= 0x3400 && content[i] <= 0x9FD5)
+ {
+ string dp = _settings.UseDoublePinyin ? ToDoublePin(resultList[i]) : resultList[i];
+ map.AddNewIndex(i, resultBuilder.Length, dp.Length + 1);
+ resultBuilder.Append(' ');
+ resultBuilder.Append(dp);
+ pre = true;
+ }
+ else
+ {
+ if (pre)
+ {
+ pre = false;
+ resultBuilder.Append(' ');
+ }
+
+ resultBuilder.Append(resultList[i]);
+ }
+ }
+
+ map.endConstruct();
+
+ var key = resultBuilder.ToString();
+ map.setKey(key);
+
+ return _pinyinCache[content] = (key, map);
}
#region Double Pinyin
private static readonly ReadOnlyDictionary special = new(new Dictionary(){
- {"a", "aa"},
- {"ai", "ai"},
- {"an", "an"},
- {"ang", "ah"},
- {"ao", "ao"},
- {"e", "ee"},
- {"ei", "ei"},
- {"en", "en"},
- {"er", "er"},
- {"o", "oo"},
- {"ou", "ou"}
+ {"A", "aa"},
+ {"Ai", "ai"},
+ {"An", "an"},
+ {"Ang", "ah"},
+ {"Ao", "ao"},
+ {"E", "ee"},
+ {"Ei", "ei"},
+ {"En", "en"},
+ {"Er", "er"},
+ {"O", "oo"},
+ {"Ou", "ou"}
});
private static readonly ReadOnlyDictionary first = new(new Dictionary(){
- {"ch", "i"},
- {"sh", "u"},
- {"zh", "v"}
+ {"Ch", "i"},
+ {"Sh", "u"},
+ {"Zh", "v"}
});
From b816d1b866aa93b6d8f2da9f5cef334bda64748b Mon Sep 17 00:00:00 2001
From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Sun, 2 Jun 2024 15:21:04 +0800
Subject: [PATCH 0018/1697] Remove unused key in pinyin alphabet
---
Flow.Launcher.Infrastructure/PinyinAlphabet.cs | 1 -
Flow.Launcher.Infrastructure/TranslationMapping.cs | 7 -------
2 files changed, 8 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
index cbec7feae..10799c676 100644
--- a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
+++ b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
@@ -83,7 +83,6 @@ namespace Flow.Launcher.Infrastructure
map.endConstruct();
var key = resultBuilder.ToString();
- map.setKey(key);
return _pinyinCache[content] = (key, map);
}
diff --git a/Flow.Launcher.Infrastructure/TranslationMapping.cs b/Flow.Launcher.Infrastructure/TranslationMapping.cs
index f288c816a..c976fc522 100644
--- a/Flow.Launcher.Infrastructure/TranslationMapping.cs
+++ b/Flow.Launcher.Infrastructure/TranslationMapping.cs
@@ -12,13 +12,6 @@ namespace Flow.Launcher.Infrastructure
private List translatedIndexs = new List();
private int translatedLength = 0;
- public string key { get; private set; }
-
- public void setKey(string key)
- {
- this.key = key;
- }
-
public void AddNewIndex(int originalIndex, int translatedIndex, int length)
{
if (constructed)
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 0019/1697] 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 ba0ddd6ab..000000000
--- 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 f275d129c..000000000
--- 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 c7a722189..bba466384 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 91f32a844..2a266f8f6 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 1ec07915d..0dbb46be9 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -18,9 +18,10 @@ using MessageBox = System.Windows.MessageBox;
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
{"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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
{
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 6fd6472db..24d17486e 100644
--- a/Plugins/Flow.Launcher.Plugin.FlowThemeSelector/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
@@ -4,14 +4,16 @@ using System.IO;
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 @@ namespace Flow.Launcher.Plugin.FlowThemeSelector
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 @@ namespace Flow.Launcher.Plugin.FlowThemeSelector
}
}
- 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 @@ namespace Flow.Launcher.Plugin.FlowThemeSelector
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 0020/1697] 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 24d17486e..758250421 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
@@ -6,7 +6,7 @@ using Flow.Launcher.Core.Resource;
namespace Flow.Launcher.Plugin.Sys
{
- public class ThemeSelector : IReloadable, IDisposable
+ public class ThemeSelector : IDisposable
{
public const string Keyword = "fltheme";
@@ -82,8 +82,6 @@ namespace Flow.Launcher.Plugin.Sys
};
}
- public void ReloadData() => LoadThemes();
-
public void Dispose()
{
if (context != null && context.API != null)
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 0021/1697] 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 5a6633525..ae4fd639d 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
@@ -133,10 +133,16 @@ namespace Flow.Launcher.Core.Plugin
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 0022/1697] [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 a2ec9405a..b8757f67b 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 39aa1738f..9b3dd06f5 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Main.cs
@@ -11,7 +11,7 @@ using Flow.Launcher.Plugin.SharedCommands;
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 @@ namespace Flow.Launcher.Plugin.WebSearch
_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 @@ namespace Flow.Launcher.Plugin.WebSearch
_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 0023/1697] [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 9b3dd06f5..bf5fadc54 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Main.cs
@@ -148,6 +148,7 @@ namespace Flow.Launcher.Plugin.WebSearch
public List LoadContextMenus(Result selected)
{
+ if (selected?.ContextData == null || selected.ContextData is not string) return new List();
return new List() {
new Result
{
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 0024/1697] 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 c95a8ce7b..e5df91ae9 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -298,5 +298,11 @@ namespace Flow.Launcher.Plugin
///
/// 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 20b02ddee..8a07e7a5c 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -318,6 +318,8 @@ namespace Flow.Launcher
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 6c17e21f0..445484347 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 @@ namespace Flow.Launcher.ViewModel
}
}
+ 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 0025/1697] 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 e5df91ae9..f3d773122 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -294,7 +294,7 @@ namespace Flow.Launcher.Plugin
///
/// 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 3ae960d275e82c88f5aabe57ad9405f028e8ceb4 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 24 Nov 2024 16:11:53 +0800
Subject: [PATCH 0026/1697] 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 b58154dcb..544cf2509 100644
--- a/Flow.Launcher.Core/Configuration/Portable.cs
+++ b/Flow.Launcher.Core/Configuration/Portable.cs
@@ -9,6 +9,7 @@ using Flow.Launcher.Infrastructure.Logger;
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 @@ namespace Flow.Launcher.Core.Configuration
#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 @@ namespace Flow.Launcher.Core.Configuration
#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 @@ namespace Flow.Launcher.Core.Configuration
{
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 @@ namespace Flow.Launcher.Core.Configuration
{
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 @@ namespace Flow.Launcher.Core.Configuration
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 f466a640e..ca543271b 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 @@ namespace Flow.Launcher.Core.Resource
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 3f64b273e..34545c771 100644
--- a/Flow.Launcher.Core/Updater.cs
+++ b/Flow.Launcher.Core/Updater.cs
@@ -17,6 +17,7 @@ using Flow.Launcher.Infrastructure.UserSettings;
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 @@ namespace Flow.Launcher.Core
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 @@ namespace Flow.Launcher.Core
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 @@ namespace Flow.Launcher.Core
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 371b2dd07..ba47a4ded 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 @@ namespace Flow.Launcher
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 5db6115ad..81e7600b8 100644
--- a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
+++ b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
@@ -6,7 +6,7 @@ using System.Linq;
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 @@ namespace Flow.Launcher
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 531b29d50..dec3506eb 100644
--- a/Flow.Launcher/CustomShortcutSetting.xaml.cs
+++ b/Flow.Launcher/CustomShortcutSetting.xaml.cs
@@ -3,6 +3,7 @@ using System;
using System.Windows;
using System.Windows.Input;
using Flow.Launcher.SettingPages.ViewModels;
+using Flow.Launcher.Core;
namespace Flow.Launcher
{
@@ -42,13 +43,13 @@ namespace Flow.Launcher
{
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 21ddf276a..8b30b8be1 100644
--- a/Flow.Launcher/Helper/HotKeyMapper.cs
+++ b/Flow.Launcher/Helper/HotKeyMapper.cs
@@ -4,8 +4,8 @@ using System;
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 class HotKeyMapper
{
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 2d0966de4..2154b058d 100644
--- a/Flow.Launcher/PriorityChangeWindow.xaml.cs
+++ b/Flow.Launcher/PriorityChangeWindow.xaml.cs
@@ -5,6 +5,7 @@ using Flow.Launcher.ViewModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
+using Flow.Launcher.Core;
namespace Flow.Launcher
{
@@ -23,7 +24,7 @@ namespace Flow.Launcher
this.pluginViewModel = pluginViewModel;
if (plugin == null)
{
- MessageBox.Show(translater.GetTranslation("cannotFindSpecifiedPlugin"));
+ MessageBoxEx.Show(translater.GetTranslation("cannotFindSpecifiedPlugin"));
Close();
}
}
@@ -43,7 +44,7 @@ namespace Flow.Launcher
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 c314b42ee..6e6cbce4d 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
@@ -11,7 +11,7 @@ using Flow.Launcher.Core.Resource;
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 a4488a037..669cd0784 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
@@ -7,6 +7,8 @@ using Flow.Launcher.Infrastructure;
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 @@ public partial class SettingsPaneHotkeyViewModel : BaseModel
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 @@ public partial class SettingsPaneHotkeyViewModel : BaseModel
var item = SelectedCustomPluginHotkey;
if (item is null)
{
- MessageBox.Show(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
+ MessageBoxEx.Show(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
return;
}
@@ -87,16 +89,16 @@ public partial class SettingsPaneHotkeyViewModel : BaseModel
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 @@ public partial class SettingsPaneHotkeyViewModel : BaseModel
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 2dd57809d..1c840fb27 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 partial class SettingsPaneProxyViewModel : BaseModel
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 f2e52dbae..8a835ba7c 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.Infrastructure.UserSettings;
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 partial class SettingsPaneThemeViewModel : BaseModel
{
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 0027/1697] 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 18b1ae07f..3e04657dc 100644
--- a/Flow.Launcher.Core/MessageBoxEx.xaml.cs
+++ b/Flow.Launcher.Core/MessageBoxEx.xaml.cs
@@ -37,39 +37,39 @@ namespace Flow.Launcher.Core
/// 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 @@ namespace Flow.Launcher.Core
}
// 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 0028/1697] 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 ca543271b..2788a7648 100644
--- a/Flow.Launcher.Core/MessageBoxEx.xaml
+++ b/Flow.Launcher.Core/MessageBoxEx.xaml
@@ -33,14 +33,11 @@
-
-
-
-
-
+
+
+
+
+
+
@@ -91,14 +95,25 @@
-
+
+
Date: Mon, 25 Nov 2024 10:38:43 +0800
Subject: [PATCH 0030/1697] 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 544cf2509..2a1db10e7 100644
--- a/Flow.Launcher.Core/Configuration/Portable.cs
+++ b/Flow.Launcher.Core/Configuration/Portable.cs
@@ -96,13 +96,13 @@ namespace Flow.Launcher.Core.Configuration
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 @@ namespace Flow.Launcher.Core.Configuration
// 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 @@ namespace Flow.Launcher.Core.Configuration
// 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 30e812c6f..433df6f97 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
@@ -6,8 +6,10 @@ 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
{
@@ -57,7 +59,7 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
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 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
}
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 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
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 5676e12f5..96c29646e 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs
@@ -28,7 +28,7 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
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 70341f711..0d6f109e0 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs
@@ -25,7 +25,7 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
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 11ed94d3f..582a4407c 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs
@@ -25,7 +25,7 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
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 91cb36a0e..5c4eaa1da 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -519,7 +519,7 @@ namespace Flow.Launcher.Core.Plugin
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 0f2e4f996..495d25e1b 100644
--- a/Flow.Launcher.Core/Plugin/PluginsLoader.cs
+++ b/Flow.Launcher.Core/Plugin/PluginsLoader.cs
@@ -3,7 +3,7 @@ using System.Collections.Generic;
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.Logger;
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 @@ namespace Flow.Launcher.Core.Plugin
_ = 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 34545c771..5a980c5e2 100644
--- a/Flow.Launcher.Core/Updater.cs
+++ b/Flow.Launcher.Core/Updater.cs
@@ -69,8 +69,8 @@ namespace Flow.Launcher.Core
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 dd8c4b112..fb2578e6d 100644
--- a/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs
+++ b/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs
@@ -21,7 +21,8 @@ namespace Flow.Launcher.Plugin.SharedCommands
///
///
///
- 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 @@ namespace Flow.Launcher.Plugin.SharedCommands
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 @@ namespace Flow.Launcher.Plugin.SharedCommands
#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 @@ namespace Flow.Launcher.Plugin.SharedCommands
///
///
///
+ ///
///
- 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 @@ namespace Flow.Launcher.Plugin.SharedCommands
#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 @@ namespace Flow.Launcher.Plugin.SharedCommands
/// 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 @@ namespace Flow.Launcher.Plugin.SharedCommands
#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 @@ namespace Flow.Launcher.Plugin.SharedCommands
/// 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 @@ namespace Flow.Launcher.Plugin.SharedCommands
#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 @@ namespace Flow.Launcher.Plugin.SharedCommands
/// 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 @@ namespace Flow.Launcher.Plugin.SharedCommands
#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 5077e6061..54a6f7a44 100644
--- a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs
@@ -3,11 +3,11 @@ using System.Collections.Generic;
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 @@ namespace Flow.Launcher.Plugin.Calculator
}
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 f061ca183..8c40cac9a 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;
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 @@ namespace Flow.Launcher.Plugin.Explorer
{
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 ef923632d..b890e6e18 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 class EverythingDownloadHelper
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 class EverythingDownloadHelper
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 1e7555a8d..bffe75c29 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
@@ -12,6 +12,7 @@ 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
{
@@ -123,7 +124,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
}
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 @@ namespace Flow.Launcher.Plugin.Explorer.Search
}
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 @@ namespace Flow.Launcher.Plugin.Explorer.Search
}
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 @@ namespace Flow.Launcher.Plugin.Explorer.Search
}
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 @@ namespace Flow.Launcher.Plugin.Explorer.Search
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 309f7a6f7..49b4a9fa2 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.Linq;
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 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
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 9e86ce4b4..fdfe1638a 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 @@ namespace Flow.Launcher.Plugin.Explorer.Views
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 @@ namespace Flow.Launcher.Plugin.Explorer.Views
}
// 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 2d71329b4..fcba3ebee 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.Net.Http;
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 @@ namespace Flow.Launcher.Plugin.PluginsManager
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 @@ namespace Flow.Launcher.Plugin.PluginsManager
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 @@ namespace Flow.Launcher.Plugin.PluginsManager
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 @@ namespace Flow.Launcher.Plugin.PluginsManager
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 @@ namespace Flow.Launcher.Plugin.PluginsManager
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 @@ namespace Flow.Launcher.Plugin.PluginsManager
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 be8b768bd..fef16cb33 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 @@ namespace Flow.Launcher.Plugin.Program
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 4d88eef2c..68363c1fa 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 31565c8b0..af1df8e71 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 @@ namespace Flow.Launcher.Plugin.Program
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 7570d6b4d..e85b7534e 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 Flow.Launcher.Plugin.Program.Programs;
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 @@ namespace Flow.Launcher.Plugin.Program.Views
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 @@ namespace Flow.Launcher.Plugin.Program.Views
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 @@ namespace Flow.Launcher.Plugin.Program.Views
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 b797b3cf4..4e804e82c 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 1ec07915d..72f3639ff 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -7,6 +7,7 @@ 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;
@@ -14,7 +15,7 @@ using Flow.Launcher.Plugin.SharedCommands;
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 60863ee82..8336f4b9a 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 @@ namespace Flow.Launcher.Plugin.WebSearch
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 @@ namespace Flow.Launcher.Plugin.WebSearch
else
{
var warning = _api.GetTranslation("newActionKeywordsHasBeenAssigned");
- MessageBox.Show(warning);
+ MessageBoxEx.Show(warning);
}
}
@@ -113,7 +114,7 @@ namespace Flow.Launcher.Plugin.WebSearch
else
{
var warning = _api.GetTranslation("newActionKeywordsHasBeenAssigned");
- MessageBox.Show(warning);
+ MessageBoxEx.Show(warning);
}
if (!string.IsNullOrEmpty(selectedNewIconImageFullPath))
@@ -138,7 +139,7 @@ namespace Flow.Launcher.Plugin.WebSearch
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 105e7dd68..0495772d5 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceViewModel.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceViewModel.cs
@@ -41,7 +41,7 @@ namespace Flow.Launcher.Plugin.WebSearch
#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 7caa5beb3..7e4edf653 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 @@ namespace Flow.Launcher.Plugin.WebSearch
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 0031/1697] Improve MessageBoxEx style as
System.Windows.MessageBox
---
Flow.Launcher.Core/MessageBoxEx.xaml | 24 ++++++++++++------------
Flow.Launcher.Core/MessageBoxEx.xaml.cs | 6 +++---
2 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/Flow.Launcher.Core/MessageBoxEx.xaml b/Flow.Launcher.Core/MessageBoxEx.xaml
index 3467b3a0c..8edb0873d 100644
--- a/Flow.Launcher.Core/MessageBoxEx.xaml
+++ b/Flow.Launcher.Core/MessageBoxEx.xaml
@@ -124,18 +124,6 @@
HorizontalAlignment="Center"
VerticalAlignment="Center"
Orientation="Horizontal">
-
-
+
+
diff --git a/Flow.Launcher.Core/MessageBoxEx.xaml.cs b/Flow.Launcher.Core/MessageBoxEx.xaml.cs
index 911e6b5b8..1a986be4c 100644
--- a/Flow.Launcher.Core/MessageBoxEx.xaml.cs
+++ b/Flow.Launcher.Core/MessageBoxEx.xaml.cs
@@ -125,16 +125,16 @@ namespace Flow.Launcher.Core
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 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/1697] 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 fb2578e6d..6e00b8a27 100644
--- a/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs
+++ b/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs
@@ -64,7 +64,7 @@ namespace Flow.Launcher.Plugin.SharedCommands
throw;
#else
messageBoxExShow(string.Format("Copying path {0} has failed, it will now be deleted for consistency", targetPath));
- RemoveFolderIfExists(targetPath);
+ RemoveFolderIfExists(targetPath, messageBoxExShow);
#endif
}
From 897fd7aabac08c098546af7a80cc3ca4d90c86c8 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 26 Nov 2024 21:31:13 +0800
Subject: [PATCH 0033/1697] 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 2a1db10e7..d7c73fb46 100644
--- a/Flow.Launcher.Core/Configuration/Portable.cs
+++ b/Flow.Launcher.Core/Configuration/Portable.cs
@@ -9,7 +9,6 @@ using Flow.Launcher.Infrastructure.Logger;
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 @@ namespace Flow.Launcher.Core.Configuration
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 433df6f97..6d41e2383 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;
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 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
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 1a986be4c..b87302ca5 100644
--- a/Flow.Launcher.Core/MessageBoxEx.xaml.cs
+++ b/Flow.Launcher.Core/MessageBoxEx.xaml.cs
@@ -13,25 +13,6 @@ namespace Flow.Launcher.Core
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 @@ namespace Flow.Launcher.Core
}
/// 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 @@ namespace Flow.Launcher.Core
{
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 495d25e1b..7973c66ba 100644
--- a/Flow.Launcher.Core/Plugin/PluginsLoader.cs
+++ b/Flow.Launcher.Core/Plugin/PluginsLoader.cs
@@ -11,7 +11,6 @@ using Flow.Launcher.Infrastructure.Logger;
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 e634dc9dd..1505e84f8 100644
--- a/Flow.Launcher.Core/Resource/Internationalization.cs
+++ b/Flow.Launcher.Core/Resource/Internationalization.cs
@@ -11,7 +11,6 @@ using Flow.Launcher.Infrastructure.UserSettings;
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 @@ namespace Flow.Launcher.Core.Resource
// "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 5a980c5e2..b92d86568 100644
--- a/Flow.Launcher.Core/Updater.cs
+++ b/Flow.Launcher.Core/Updater.cs
@@ -17,7 +17,6 @@ using Flow.Launcher.Infrastructure.UserSettings;
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 @@ namespace Flow.Launcher.Core
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
Date: Tue, 26 Nov 2024 22:02:24 +0800
Subject: [PATCH 0034/1697] 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 8edb0873d..10326c687 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 b87302ca5..4e50f4664 100644
--- a/Flow.Launcher.Core/MessageBoxEx.xaml.cs
+++ b/Flow.Launcher.Core/MessageBoxEx.xaml.cs
@@ -16,62 +16,52 @@ namespace Flow.Launcher.Core
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 @@ namespace Flow.Launcher.Core
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 @@ namespace Flow.Launcher.Core
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_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/1697] 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 10326c687..fff107a68 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 4e50f4664..b94d594ee 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 @@ namespace Flow.Launcher.Core
// 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 @@ namespace Flow.Launcher.Core
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 @@ namespace Flow.Launcher.Core
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/1697] 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 b94d594ee..bca20c067 100644
--- a/Flow.Launcher.Core/MessageBoxEx.xaml.cs
+++ b/Flow.Launcher.Core/MessageBoxEx.xaml.cs
@@ -3,6 +3,7 @@ using System.Windows;
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 @@ namespace Flow.Launcher.Core
{
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 @@ namespace Flow.Launcher.Core
// 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.Title = caption;
- msgBox.TitleTextBlock.Text = caption;
- msgBox.DescTextBlock.Text = messageBoxText;
- SetImageOfMessageBox(icon);
+ 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)
+ {
+ 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 @@ namespace Flow.Launcher.Core
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/1697] 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 c95a8ce7b..a747ba340 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -7,6 +7,7 @@ using System.IO;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
+using System.Windows;
namespace Flow.Launcher.Plugin
{
@@ -298,5 +299,81 @@ namespace Flow.Launcher.Plugin
///
/// 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 20b02ddee..33739bda2 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -25,6 +25,7 @@ using Flow.Launcher.Infrastructure.Storage;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Collections.Specialized;
+using Flow.Launcher.Core;
namespace Flow.Launcher
{
@@ -318,6 +319,19 @@ namespace Flow.Launcher
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/1697] 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 54a6f7a44..7f42eacf6 100644
--- a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs
@@ -7,7 +7,6 @@ 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 +100,7 @@ namespace Flow.Launcher.Plugin.Calculator
}
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 b13d89f2c..feccc74c8 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs
@@ -11,7 +11,6 @@ using Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks;
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 @@ namespace Flow.Launcher.Plugin.Explorer
{
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 ddeec0064..d2f760f93 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 class EverythingDownloadHelper
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 class EverythingDownloadHelper
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 bffe75c29..d42c477e1 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;
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 @@ namespace Flow.Launcher.Plugin.Explorer.Search
}
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 @@ namespace Flow.Launcher.Plugin.Explorer.Search
}
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 @@ namespace Flow.Launcher.Plugin.Explorer.Search
}
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 @@ namespace Flow.Launcher.Plugin.Explorer.Search
}
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 @@ namespace Flow.Launcher.Plugin.Explorer.Search
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 49b4a9fa2..d2b85e687 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 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
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 fdfe1638a..34a5b2760 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.ComponentModel;
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 @@ namespace Flow.Launcher.Plugin.Explorer.Views
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 @@ namespace Flow.Launcher.Plugin.Explorer.Views
}
// 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 fd978c6d1..305d248d3 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 @@ namespace Flow.Launcher.Plugin.PluginsManager
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 @@ namespace Flow.Launcher.Plugin.PluginsManager
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 @@ namespace Flow.Launcher.Plugin.PluginsManager
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 @@ namespace Flow.Launcher.Plugin.PluginsManager
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 @@ namespace Flow.Launcher.Plugin.PluginsManager
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 @@ namespace Flow.Launcher.Plugin.PluginsManager
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 fef16cb33..6385ab364 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 @@ namespace Flow.Launcher.Plugin.Program
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 68363c1fa..4d88eef2c 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 af1df8e71..55d44bdc2 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 @@ namespace Flow.Launcher.Plugin.Program
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 c7595c49d..36b5acc8a 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 Flow.Launcher.Plugin.Program.Programs;
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 @@ namespace Flow.Launcher.Plugin.Program.Views
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 @@ namespace Flow.Launcher.Plugin.Program.Views
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 @@ namespace Flow.Launcher.Plugin.Program.Views
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 4e804e82c..b797b3cf4 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 94e83315b..6e5558228 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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 8336f4b9a..a3e5630c2 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 @@ namespace Flow.Launcher.Plugin.WebSearch
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 @@ namespace Flow.Launcher.Plugin.WebSearch
else
{
var warning = _api.GetTranslation("newActionKeywordsHasBeenAssigned");
- MessageBoxEx.Show(warning);
+ _context.API.ShowMsgBox(warning);
}
}
@@ -114,7 +113,7 @@ namespace Flow.Launcher.Plugin.WebSearch
else
{
var warning = _api.GetTranslation("newActionKeywordsHasBeenAssigned");
- MessageBoxEx.Show(warning);
+ _context.API.ShowMsgBox(warning);
}
if (!string.IsNullOrEmpty(selectedNewIconImageFullPath))
@@ -139,7 +138,7 @@ namespace Flow.Launcher.Plugin.WebSearch
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 75f436013..739bc9d6b 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs
@@ -3,7 +3,6 @@ using System.Windows.Controls;
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 @@ namespace Flow.Launcher.Plugin.WebSearch
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/1697] 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 052c296cd..50ce96ded 100644
--- a/Flow.Launcher/Storage/TopMostRecord.cs
+++ b/Flow.Launcher/Storage/TopMostRecord.cs
@@ -12,7 +12,7 @@ namespace Flow.Launcher.Storage
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/1697] 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 612f495be..c5bba9fed 100644
--- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
@@ -215,8 +215,15 @@ namespace Flow.Launcher.Infrastructure.Image
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 @@ namespace Flow.Launcher.Infrastructure.Image
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/1697] 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 c5bba9fed..4592269a2 100644
--- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
@@ -223,6 +223,7 @@ namespace Flow.Launcher.Infrastructure.Image
catch (NotSupportedException)
{
image = null;
+ type = ImageType.Error;
}
}
else
@@ -249,7 +250,7 @@ namespace Flow.Launcher.Infrastructure.Image
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/1697] 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 50ce96ded..a088353f5 100644
--- a/Flow.Launcher/Storage/TopMostRecord.cs
+++ b/Flow.Launcher/Storage/TopMostRecord.cs
@@ -18,7 +18,7 @@ namespace Flow.Launcher.Storage
}
// 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/1697] 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 a088353f5..069b670cb 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 @@ namespace Flow.Launcher.Storage
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 @@ namespace Flow.Launcher.Storage
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/1697] 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 6afe1e91f..d6405005d 100644
--- a/Flow.Launcher/Storage/UserSelectedRecord.cs
+++ b/Flow.Launcher/Storage/UserSelectedRecord.cs
@@ -51,6 +51,11 @@ namespace Flow.Launcher.Storage
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 @@ namespace Flow.Launcher.Storage
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/1697] Fix result update issue during modified collection
enumeration
---
Flow.Launcher/ViewModel/MainViewModel.cs | 37 ++++++++++++++----------
1 file changed, 22 insertions(+), 15 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 6c17e21f0..f07d5c6dd 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 @@ namespace Flow.Launcher.ViewModel
}
#endif
- foreach (var metaResults in resultsForUpdates)
+ try
{
- foreach (var result in metaResults.Results)
+ foreach (var metaResults in resultsForUpdates)
{
- if (_topMostRecord.IsTopMost(result))
+ foreach (var result in metaResults.Results)
{
- result.Score = int.MaxValue;
- }
- else
- {
- 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;
+
+ 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 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/1697] 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 b9ad97534..f5fd729d4 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/ProgressBoxEx.xaml.cs b/Flow.Launcher/ProgressBoxEx.xaml.cs
index 7c55d62c0..755fc4a1f 100644
--- a/Flow.Launcher/ProgressBoxEx.xaml.cs
+++ b/Flow.Launcher/ProgressBoxEx.xaml.cs
@@ -95,14 +95,19 @@ namespace Flow.Launcher
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 0273/1697] 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 64434b49c..9e0777a98 100644
--- a/Flow.Launcher/Helper/HotKeyMapper.cs
+++ b/Flow.Launcher/Helper/HotKeyMapper.cs
@@ -8,6 +8,7 @@ using Flow.Launcher.ViewModel;
using Flow.Launcher.Core;
using ChefKeys;
using System.Globalization;
+using Flow.Launcher.Infrastructure.Logger;
namespace Flow.Launcher.Helper;
@@ -39,38 +40,49 @@ internal static class HotKeyMapper
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 class HotKeyMapper
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 4c465d61f..00523d03d 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 0274/1697] 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 32b0f64b4..d201e50bd 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 0275/1697] 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 d201e50bd..c17f8b61d 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 0276/1697] 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 e0a0434a2..a82cae5d2 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs
@@ -170,10 +170,5 @@ namespace Flow.Launcher.Core.Plugin.JsonRPCV2Models
{
_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 8376fd07b..1a8da381b 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 @@ namespace Flow.Launcher.Plugin
///
/// 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 fd829afe2..81e7600b8 100644
--- a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
+++ b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
@@ -76,8 +76,6 @@ namespace Flow.Launcher
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 d05a5c15c..dec3506eb 100644
--- a/Flow.Launcher/CustomShortcutSetting.xaml.cs
+++ b/Flow.Launcher/CustomShortcutSetting.xaml.cs
@@ -64,8 +64,6 @@ namespace Flow.Launcher
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 7706a64ba..d7f052af3 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -319,8 +319,6 @@ namespace Flow.Launcher
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 834692536..ac51b195c 100644
--- a/Flow.Launcher/ResultListBox.xaml.cs
+++ b/Flow.Launcher/ResultListBox.xaml.cs
@@ -149,11 +149,7 @@ namespace Flow.Launcher
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 4af93daf9..d8e33ad14 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -279,10 +279,8 @@ namespace Flow.Launcher.ViewModel
public void ReQuery(bool reselect)
{
- if (SelectedIsFromQueryResults())
- {
- QueryResults(isReQuery: true, reSelect: reselect);
- }
+ BackToQueryResults();
+ QueryResults(isReQuery: true, reSelect: reselect);
}
[RelayCommand]
@@ -491,7 +489,7 @@ namespace Flow.Launcher.ViewModel
}
}
- public void BackToQueryResults()
+ private void BackToQueryResults()
{
if (!SelectedIsFromQueryResults())
{
@@ -610,6 +608,8 @@ namespace Flow.Launcher.ViewModel
{
Application.Current.Dispatcher.Invoke(() =>
{
+ BackToQueryResults();
+
if (QueryText != queryText)
{
// re-query is done in QueryText's setter method
@@ -1266,8 +1266,6 @@ namespace Flow.Launcher.ViewModel
{
_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 @@ namespace Flow.Launcher.ViewModel
{
_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 7675ecb16..38b5bec65 100644
--- a/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs
@@ -64,8 +64,6 @@ namespace Flow.Launcher.ViewModel
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 c8601c431..447f06860 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -146,8 +146,6 @@ namespace Flow.Launcher.ViewModel
[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 @@ namespace Flow.Launcher.ViewModel
changeKeywordsWindow.ShowDialog();
}
}
-
}
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
index 6ba7047f2..c08853df8 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -264,7 +264,6 @@ namespace Flow.Launcher.Plugin.Program
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 86808cfbc..62076b494 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
@@ -382,7 +382,6 @@ namespace Flow.Launcher.Plugin.Shell
{
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 0277/1697] 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 1a8da381b..28cc1fc91 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -305,6 +305,12 @@ namespace Flow.Launcher.Plugin
/// 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 d7f052af3..7706a64ba 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -319,6 +319,8 @@ namespace Flow.Launcher
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 d8e33ad14..0d1f5655b 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -489,7 +489,7 @@ namespace Flow.Launcher.ViewModel
}
}
- 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 0278/1697] 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 a82cae5d2..e0a0434a2 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs
@@ -170,5 +170,10 @@ namespace Flow.Launcher.Core.Plugin.JsonRPCV2Models
{
_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 0279/1697] 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 28cc1fc91..9b608d14f 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -18,7 +18,7 @@ namespace Flow.Launcher.Plugin
{
///
/// 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 @@ namespace Flow.Launcher.Plugin
///
/// 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 62076b494..53479b81f 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
@@ -381,7 +381,6 @@ namespace Flow.Launcher.Plugin.Shell
_ = 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 0280/1697] 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 9b608d14f..bf8bbf44a 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -300,7 +300,7 @@ namespace Flow.Launcher.Plugin
///
/// 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 0281/1697] 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 bf8bbf44a..07fc378c3 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -18,7 +18,7 @@ namespace Flow.Launcher.Plugin
{
///
/// 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 0282/1697] 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 3dead9918..2621fc2da 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 @@ namespace Flow.Launcher.Test
[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 @@ namespace Flow.Launcher.Test
[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 d7f143218..9d3b7e70f 100644
--- a/Flow.Launcher.Test/FuzzyMatcherTest.cs
+++ b/Flow.Launcher.Test/FuzzyMatcherTest.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
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 @@ namespace Flow.Launcher.Test
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 @@ namespace Flow.Launcher.Test
OneOneOneOne
};
- public List GetPrecisionScores()
+ public static List GetPrecisionScores()
{
var listToReturn = new List();
@@ -71,10 +72,10 @@ namespace Flow.Launcher.Test
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 @@ namespace Flow.Launcher.Test
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 @@ namespace Flow.Launcher.Test
Debug.WriteLine("###############################################");
Debug.WriteLine("");
- Assert.IsFalse(filteredResult.Any(x => x.Score < precisionScore));
+ ClassicAssert.IsFalse(filteredResult.Any(x => x.Score < precisionScore));
}
}
@@ -151,7 +152,7 @@ namespace Flow.Launcher.Test
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 @@ namespace Flow.Launcher.Test
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 @@ namespace Flow.Launcher.Test
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 @@ namespace Flow.Launcher.Test
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 @@ namespace Flow.Launcher.Test
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 @@ namespace Flow.Launcher.Test
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 @@ namespace Flow.Launcher.Test
{
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 e72ad7a67..4f135978a 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 @@ namespace Flow.Launcher.Test
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 d6ba48f19..2cc05f95a 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 @@ namespace Flow.Launcher.Test
// 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 @@ namespace Flow.Launcher.Test
(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 @@ namespace Flow.Launcher.Test
// 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 @@ namespace Flow.Launcher.Test
(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 80cb74729..420da266d 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.DirectoryInfo;
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 @@ namespace Flow.Launcher.Test.Plugins
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 @@ namespace Flow.Launcher.Test.Plugins
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 @@ namespace Flow.Launcher.Test.Plugins
var queryString = queryConstructor.Directory(folderPath, userSearchString);
// Then
- Assert.AreEqual(expectedString, queryString);
+ ClassicAssert.AreEqual(expectedString, queryString);
}
[SupportedOSPlatform("windows7.0")]
@@ -105,7 +81,7 @@ namespace Flow.Launcher.Test.Plugins
const string resultString = QueryConstructor.RestrictionsForAllFilesAndFoldersSearch;
// Then
- Assert.AreEqual(expectedString, resultString);
+ ClassicAssert.AreEqual(expectedString, resultString);
}
[SupportedOSPlatform("windows7.0")]
@@ -128,7 +104,7 @@ namespace Flow.Launcher.Test.Plugins
var resultString = queryConstructor.FilesAndFolders(userSearchString);
// Then
- Assert.AreEqual(expectedString, resultString);
+ ClassicAssert.AreEqual(expectedString, resultString);
}
@@ -138,13 +114,13 @@ namespace Flow.Launcher.Test.Plugins
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 @@ namespace Flow.Launcher.Test.Plugins
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 @@ namespace Flow.Launcher.Test.Plugins
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 @@ namespace Flow.Launcher.Test.Plugins
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 @@ namespace Flow.Launcher.Test.Plugins
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 @@ namespace Flow.Launcher.Test.Plugins
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 @@ namespace Flow.Launcher.Test.Plugins
var resultString = QueryConstructor.RecursiveDirectoryConstraint(path);
// Then
- Assert.AreEqual(expectedString, resultString);
+ ClassicAssert.AreEqual(expectedString, resultString);
}
[SupportedOSPlatform("windows7.0")]
@@ -274,7 +250,7 @@ namespace Flow.Launcher.Test.Plugins
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 @@ namespace Flow.Launcher.Test.Plugins
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 @@ namespace Flow.Launcher.Test.Plugins
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 @@ namespace Flow.Launcher.Test.Plugins
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 @@ namespace Flow.Launcher.Test.Plugins
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 @@ namespace Flow.Launcher.Test.Plugins
};
// 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 @@ namespace Flow.Launcher.Test.Plugins
var hash2 = comparator.GetHashCode(result2);
// When, Then
- Assert.IsTrue(hash1 == hash2);
+ ClassicAssert.IsTrue(hash1 == hash2);
}
[TestCase(@"%appdata%", true)]
@@ -461,7 +437,7 @@ namespace Flow.Launcher.Test.Plugins
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 42a4630fe..497f874e7 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 @@ namespace Flow.Launcher.Test.Plugins
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 @@ namespace Flow.Launcher.Test.Plugins
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 7ccac5bd5..0dd1fe489 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 @@ namespace Flow.Launcher.Test
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 aa0c8da12..c8ac17748 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 @@ namespace Flow.Launcher.Test
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 @@ namespace Flow.Launcher.Test
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 @@ namespace Flow.Launcher.Test
{
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 0283/1697] 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 2c2feeae1..ed975aa9d 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -12,6 +12,9 @@ using Flow.Launcher.Infrastructure;
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 @@ namespace Flow.Launcher.Core.Resource
_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 @@ namespace Flow.Launcher.Core.Resource
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 867fef4f5..856748537 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 10fc3583b..22594217f 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 41dc68fd9..abb959ad8 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -60,7 +60,6 @@ namespace Flow.Launcher
InitializePosition();
InitSoundEffects();
-
DataObject.AddPastingHandler(QueryTextBox, OnPaste);
this.Loaded += (_, _) =>
@@ -182,6 +181,9 @@ namespace Flow.Launcher
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 0284/1697] 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 ed975aa9d..3ebcd65c7 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -15,6 +15,7 @@ using System.Windows.Shell;
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 @@ namespace Flow.Launcher.Core.Resource
// 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 @@ namespace Flow.Launcher.Core.Resource
///
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 @@ namespace Flow.Launcher.Core.Resource
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 @@ namespace Flow.Launcher.Core.Resource
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 @@ namespace Flow.Launcher.Core.Resource
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 22594217f..d99787a8d 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 abb959ad8..8270150c2 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -61,7 +61,6 @@ namespace Flow.Launcher
InitSoundEffects();
DataObject.AddPastingHandler(QueryTextBox, OnPaste);
-
this.Loaded += (_, _) =>
{
var handle = new WindowInteropHelper(this).Handle;
@@ -107,6 +106,7 @@ namespace Flow.Launcher
return IntPtr.Zero;
}
+
private void OnResizeEnd()
{
int shadowMargin = 0;
@@ -181,7 +181,6 @@ namespace Flow.Launcher
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 8d8ccb780..ab2419d99 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
@@ -39,6 +39,7 @@ public partial class SettingsPaneThemeViewModel : BaseModel
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 5d0fc2c3c..63fb83609 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 4fe3c0495..52758171a 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 0345/1697] 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 493528a89..5d2cb2d9e 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 12ffe3ffc..6fe90783e 100644
--- a/Flow.Launcher/ReportWindow.xaml.cs
+++ b/Flow.Launcher/ReportWindow.xaml.cs
@@ -6,10 +6,10 @@ using System.Text;
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 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
{
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 0346/1697] 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 8376fd07b..ef22b697e 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -322,17 +322,16 @@ namespace Flow.Launcher.Plugin
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 755fc4a1f..2395bdf34 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 @@ namespace Flow.Launcher
{
await Application.Current.Dispatcher.InvokeAsync(() =>
{
- prgBox = new ProgressBoxEx(forceClosed)
+ prgBox = new ProgressBoxEx(cancelProgress)
{
Title = caption
};
@@ -35,7 +35,7 @@ namespace Flow.Launcher
}
else
{
- prgBox = new ProgressBoxEx(forceClosed)
+ prgBox = new ProgressBoxEx(cancelProgress)
{
Title = caption
};
@@ -113,7 +113,7 @@ namespace Flow.Launcher
private void ForceClose()
{
Close();
- _forceClosed?.Invoke();
+ _cancelProgress?.Invoke();
}
}
}
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 7706a64ba..848d7f14c 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -324,7 +324,7 @@ namespace Flow.Launcher
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 0347/1697] 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 6877253c4..3944f6b75 100644
--- a/Flow.Launcher/Resources/Controls/InstalledPluginDisplayKeyword.xaml
+++ b/Flow.Launcher/Resources/Controls/InstalledPluginDisplayKeyword.xaml
@@ -20,7 +20,7 @@
Visibility="{Binding ActionKeywordsVisibility}">
+ Content="{DynamicResource select}" />
+ Content="{DynamicResource select}" />
Date: Sat, 1 Mar 2025 22:29:14 +0800
Subject: [PATCH 0384/1697] 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 0729fba42..69934e9f4 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
@@ -325,8 +325,8 @@ namespace Flow.Launcher.Core.Plugin
{
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 e525c84ad..a5e5f6007 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 0385/1697] 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 69934e9f4..388f0b2c9 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
@@ -29,8 +29,10 @@ namespace Flow.Launcher.Core.Plugin
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 @@ namespace Flow.Launcher.Core.Plugin
VerticalAlignment = VerticalAlignment.Center,
Margin = SettingPanelItemTopBottomMargin,
TextAlignment = TextAlignment.Left,
- TextWrapping = TextWrapping.Wrap // TODO: Check password and others
+ TextWrapping = TextWrapping.Wrap
};
break;
@@ -238,7 +240,7 @@ namespace Flow.Launcher.Core.Plugin
{
var textBox = new TextBox()
{
- MinWidth = SettingPanelTextBlockMinWidth,
+ MinWidth = SettingPanelTextBoxMinWidth,
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Center,
Margin = SettingPanelItemLeftTopBottomMargin,
@@ -260,7 +262,7 @@ namespace Flow.Launcher.Core.Plugin
{
var textBox = new TextBox()
{
- MinWidth = SettingPanelPathTextBlockMinWidth,
+ MinWidth = SettingPanelPathTextBoxMinWidth,
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Center,
Margin = SettingPanelItemLeftMargin,
@@ -325,8 +327,8 @@ namespace Flow.Launcher.Core.Plugin
{
var textBox = new TextBox()
{
- MinHeight = 150,
- MinWidth = 240,
+ MinHeight = SettingPanelAreaTextBoxMinHeight,
+ MinWidth = SettingPanelAreaTextBoxMinWidth,
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Center,
Margin = SettingPanelItemLeftTopBottomMargin,
@@ -349,15 +351,16 @@ namespace Flow.Launcher.Core.Plugin
{
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 e10539c8e..65002a3a0 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 a5e5f6007..709b18051 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 0386/1697] 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 a13f3bfcc..ed290d0c8 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 ba162fe9c..5ba82f12e 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 ed290d0c8..29fe38a9c 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 d6f9813d0..a8b04d640 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 0392/1697] 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 a28b4ae0c..920894896 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
@@ -30,7 +30,7 @@ namespace Flow.Launcher.Core.Plugin
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 @@ namespace Flow.Launcher.Core.Plugin
{
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 b646cb695..10d7ff987 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 709b18051..5989192f4 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 0393/1697] 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 d2d2afa09..ded6e0e27 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 0394/1697] 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 920894896..c9a0d6e47 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
@@ -357,7 +357,6 @@ namespace Flow.Launcher.Core.Plugin
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 0395/1697] 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 f4c8a66da..4ceadec56 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -593,7 +593,10 @@ namespace Flow.Launcher.Plugin.PluginsManager
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 0396/1697] 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 39aa2d6f4..e871dd29a 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -149,12 +149,12 @@ namespace Flow.Launcher.Core.Resource
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 d99787a8d..c2e1978f9 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 0397/1697] Change AddShadow Logic
---
Flow.Launcher.Core/Resource/Theme.cs | 186 ++++++++++++------
.../ViewModels/SettingsPaneThemeViewModel.cs | 16 +-
2 files changed, 136 insertions(+), 66 deletions(-)
diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs
index e871dd29a..e64df9c87 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -153,10 +153,69 @@ namespace Flow.Launcher.Core.Resource
//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 @@ namespace Flow.Launcher.Core.Resource
}
BlurEnabled = Win32Helper.IsBlurTheme();
-
- if (_settings.UseDropShadowEffect && !BlurEnabled)
+ if (_settings.UseDropShadowEffect)
AddDropShadowEffectToCurrentTheme();
+
+
//Win32Helper.SetBlurForWindow(Application.Current.MainWindow, BlurEnabled);
SetBlurForWindow();
}
@@ -656,76 +716,86 @@ namespace Flow.Launcher.Core.Resource
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 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);
+ 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(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);
- //}
+ 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 cd5abb958..1437a7d1a 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
@@ -53,14 +53,14 @@ public partial class SettingsPaneThemeViewModel : BaseModel
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 0398/1697] 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 e64df9c87..2bf8a5d35 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -153,23 +153,26 @@ namespace Flow.Launcher.Core.Resource
//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 @@ namespace Flow.Launcher.Core.Resource
}
else
{
+ SetWindowCornerPreference("Default");
Debug.WriteLine("이거는 블러없는 테마");
AddDropShadowEffectToCurrentTheme();
}
@@ -247,6 +251,7 @@ namespace Flow.Launcher.Core.Resource
///
public void SetBlurForWindow()
{
+ //AutoDropShadow();
//SetWindowAccent();
var dict = GetThemeResourceDictionary(_settings.Theme);
if (dict == null)
@@ -265,6 +270,7 @@ namespace Flow.Launcher.Core.Resource
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 @@ namespace Flow.Launcher.Core.Resource
// 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 @@ namespace Flow.Launcher.Core.Resource
}
else
{
+ //Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, 0);
mainWindow.Background = new SolidColorBrush(Colors.Transparent);
}
}
@@ -716,14 +737,9 @@ namespace Flow.Launcher.Core.Resource
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 @@ namespace Flow.Launcher.Core.Resource
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 cd6dda39d..ae1f5d04c 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -67,11 +67,6 @@ namespace Flow.Launcher
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 1437a7d1a..d05fe98a8 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
@@ -38,6 +38,7 @@ public partial class SettingsPaneThemeViewModel : BaseModel
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 0399/1697] 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 ae1f5d04c..0e86023bb 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -67,8 +67,67 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
_ => _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 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
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 8140d80e2..43878266e 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1385,15 +1385,14 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
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 0400/1697] 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 3f1bae090..3616e4c59 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -445,7 +445,7 @@ namespace Flow.Launcher
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 98fb47288..8d4312ba5 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 @@ namespace Flow.Launcher.Resources.Pages
{
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 @@ namespace Flow.Launcher.Resources.Pages
}
}
-}
\ 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 1ed5747cd..4a4679a4a 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 @@ namespace Flow.Launcher.Resources.Pages
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 9051e7c27..38cb8642a 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 @@ namespace Flow.Launcher.Resources.Pages
{
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 11bbcd6ed..fc6568935 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 @@ namespace Flow.Launcher.Resources.Pages
{
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 abb805303..5327eb5c8 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 @@ namespace Flow.Launcher.Resources.Pages
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 ade650284..6606b00f0 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
@@ -54,7 +54,7 @@ public partial class SettingsPaneAboutViewModel : BaseModel
[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 c3723a8c5..1d55b5741 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 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
{
pageNum--;
UpdateView();
- ContentFrame.Navigate(PageTypeSelector(pageNum), settings, _backTransitionInfo);
+ ContentFrame.Navigate(PageTypeSelector(pageNum), null, _backTransitionInfo);
}
else
{
@@ -109,7 +105,7 @@ namespace Flow.Launcher
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 0401/1697] 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 70ebb404b..ccf4de870 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 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
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 a4d21a782..2f8c5eb26 100644
--- a/Flow.Launcher/HotkeyControlDialog.xaml.cs
+++ b/Flow.Launcher/HotkeyControlDialog.xaml.cs
@@ -4,9 +4,11 @@ using System.Linq;
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 partial class HotkeyControlDialog : ContentDialog
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 partial class HotkeyControlDialog : ContentDialog
};
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 6c6fcbb62..04c76d027 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 22e3960ef..b1d72ede5 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 0402/1697] 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 869774882..273d18e3f 100644
--- a/Flow.Launcher/HotkeyControl.xaml.cs
+++ b/Flow.Launcher/HotkeyControl.xaml.cs
@@ -111,7 +111,7 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
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 0403/1697] 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 de6a4df5e..1ecc02aa6 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 @@ public partial class SettingsPaneAbout
{
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 f95015b2e..dd7fd13a9 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 @@ public partial class SettingsPaneGeneral
{
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 061eabf51..eb100da0c 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 @@ public partial class SettingsPaneHotkey
{
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 db4763319..3bd24bc13 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 @@ public partial class SettingsPanePluginStore
{
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 d48505c3d..f6b435186 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 @@ public partial class SettingsPanePlugins
{
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 95c88d627..26350b8bb 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 @@ public partial class SettingsPaneProxy
{
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 7f32728c2..bf7502e19 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 @@ public partial class SettingsPaneTheme : Page
{
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 f87194c30..30b51f992 100644
--- a/Flow.Launcher/SettingWindow.xaml.cs
+++ b/Flow.Launcher/SettingWindow.xaml.cs
@@ -4,8 +4,6 @@ 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;
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 partial class 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 @@ public partial class SettingWindow
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 @@ public partial class SettingWindow
nameof(About) => typeof(SettingsPaneAbout),
_ => typeof(SettingsPaneGeneral)
};
- ContentFrame.Navigate(pageType, paneData);
+ ContentFrame.Navigate(pageType);
}
}
@@ -211,6 +204,4 @@ public partial class SettingWindow
{
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 0404/1697] 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 33d13614f..8f6e47bbb 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 0405/1697] 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 | 66 ++++++++----------
9 files changed, 132 insertions(+), 47 deletions(-)
create mode 100644 Flow.Launcher/ViewModel/WelcomeViewModel.cs
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 447eca792..07b721b99 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -64,6 +64,7 @@ namespace Flow.Launcher
.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 8d4312ba5..880bfd9bc 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs
@@ -3,6 +3,7 @@ using System.Windows.Navigation;
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 @@ namespace Flow.Launcher.Resources.Pages
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 4a4679a4a..786b4d506 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs
@@ -16,6 +16,9 @@ namespace Flow.Launcher.Resources.Pages
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 38cb8642a..f59b65c1c 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 @@ namespace Flow.Launcher.Resources.Pages
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 fc6568935..4c83f3a83 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 @@ namespace Flow.Launcher.Resources.Pages
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 5327eb5c8..95d7ff1a0 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage5.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage5.xaml.cs
@@ -4,6 +4,7 @@ using Flow.Launcher.Infrastructure.UserSettings;
using Microsoft.Win32;
using Flow.Launcher.Infrastructure;
using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.ViewModel;
namespace Flow.Launcher.Resources.Pages
{
@@ -16,6 +17,9 @@ namespace Flow.Launcher.Resources.Pages
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 000000000..5eecabfde
--- /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 73f423d0b..e7c483f89 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 1d55b5741..637f9448d 100644
--- a/Flow.Launcher/WelcomeWindow.xaml.cs
+++ b/Flow.Launcher/WelcomeWindow.xaml.cs
@@ -4,69 +4,55 @@ 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;
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";
-
- private void UpdateView()
+ public WelcomeWindow()
{
- PageNavigation.Text = PageDisplay;
- if (pageNum == 1)
- {
- BackButton.IsEnabled = false;
- NextButton.IsEnabled = true;
- }
- else if (pageNum == MaxPage)
- {
- BackButton.IsEnabled = true;
- NextButton.IsEnabled = false;
- }
- else
- {
- BackButton.IsEnabled = true;
- NextButton.IsEnabled = true;
- }
+ _viewModel = Ioc.Default.GetRequiredService();
+ DataContext = _viewModel;
+ InitializeComponent();
}
private void ForwardButton_Click(object sender, RoutedEventArgs e)
{
- pageNum++;
- UpdateView();
-
- ContentFrame.Navigate(PageTypeSelector(pageNum), null, _transitionInfo);
+ if (_viewModel.PageNum < WelcomeViewModel.MaxPageNum)
+ {
+ _viewModel.PageNum++;
+ ContentFrame.Navigate(PageTypeSelector(_viewModel.PageNum), null, _forwardTransitionInfo);
+ }
+ else
+ {
+ _viewModel.NextEnabled = false;
+ }
}
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 @@ namespace Flow.Launcher
{
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 0406/1697] 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 ae1f5d04c..e4c92b936 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -509,7 +509,7 @@ namespace Flow.Launcher
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 0407/1697] 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 e4c92b936..ae1f5d04c 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -509,7 +509,7 @@ namespace Flow.Launcher
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 43878266e..fa64348cf 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1385,7 +1385,7 @@ namespace Flow.Launcher.ViewModel
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 0408/1697] 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 2bf8a5d35..edf1da05e 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -139,7 +139,6 @@ namespace Flow.Launcher.Core.Resource
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 @@ namespace Flow.Launcher.Core.Resource
//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 @@ namespace Flow.Launcher.Core.Resource
RemoveDropShadowEffectFromCurrentTheme();
if (BlurEnabled)
{
- Debug.WriteLine("이거는 블러있는 테마이므로 외곽선 주고 그림자");
SetWindowCornerPreference("Round");
}
else
{
SetWindowCornerPreference("Default");
- Debug.WriteLine("이거는 블러없는 테마");
AddDropShadowEffectToCurrentTheme();
}
}
@@ -251,7 +239,7 @@ namespace Flow.Launcher.Core.Resource
///
public void SetBlurForWindow()
{
- //AutoDropShadow();
+
//SetWindowAccent();
var dict = GetThemeResourceDictionary(_settings.Theme);
if (dict == null)
@@ -270,7 +258,7 @@ namespace Flow.Launcher.Core.Resource
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 @@ namespace Flow.Launcher.Core.Resource
// 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 @@ namespace Flow.Launcher.Core.Resource
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 @@ namespace Flow.Launcher.Core.Resource
}
}
- return Colors.Transparent; // 기본값: 투명
+ return Colors.Transparent; // Default is transparent
}
public void ThemeModeColor(string Mode)
@@ -350,26 +326,25 @@ namespace Flow.Launcher.Core.Resource
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 @@ namespace Flow.Launcher.Core.Resource
{
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 @@ namespace Flow.Launcher.Core.Resource
}
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 @@ namespace Flow.Launcher.Core.Resource
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 ae1f5d04c..e4c92b936 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -509,7 +509,7 @@ namespace Flow.Launcher
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 0409/1697] 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 fa64348cf..71bc36b2d 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -26,6 +26,7 @@ using System.ComponentModel;
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 @@ namespace Flow.Launcher.ViewModel
});
}
- public void Hide()
+ public async void Hide()
{
lastHistoryIndex = 1;
@@ -1407,18 +1408,47 @@ namespace Flow.Launcher.ViewModel
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 0410/1697] 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 e4c92b936..a66104103 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -27,6 +27,9 @@ using DataObject = System.Windows.DataObject;
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 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
_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 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
windowsb.Completed += (_, _) => _animating = false;
_settings.WindowLeft = Left;
- _settings.WindowTop = Top;
isArrowKeyPressed = false;
if (QueryTextBox.Text.Length == 0)
@@ -581,6 +614,8 @@ namespace Flow.Launcher
windowsb.Begin(FlowMainWindow);
}
+
+
private void InitSoundEffects()
{
if (_settings.WMPInstalled)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 71bc36b2d..8caac5ec4 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1393,11 +1393,15 @@ namespace Flow.Launcher.ViewModel
});
}
- 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 @@ namespace Flow.Launcher.ViewModel
SelectedResults = Results;
}
- // 📌 모든 LastQueryMode에서 텍스트 필드 즉시 업데이트 + 강제 UI 갱신
Application.Current.Dispatcher.Invoke(() =>
{
switch (Settings.LastQueryMode)
@@ -1437,11 +1440,9 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
+
///
/// 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 0411/1697] 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 a66104103..588acbdf8 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -530,7 +530,7 @@ namespace Flow.Launcher
// 📌 항상 같은 위치에서 시작하도록 `_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 8caac5ec4..aa3682810 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -27,6 +27,8 @@ using Flow.Launcher.Infrastructure.Image;
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 @@ namespace Flow.Launcher.ViewModel
}
}
+ // 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 @@ namespace Flow.Launcher.ViewModel
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.Selected:
+ 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;
+ 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 0412/1697] 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 aa3682810..55e1e38cd 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1404,7 +1404,8 @@ namespace Flow.Launcher.ViewModel
// 📌 창을 먼저 보이게 설정
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 @@ namespace Flow.Launcher.ViewModel
// 📌 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 0413/1697] 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 55e1e38cd..3249fd221 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1422,9 +1422,6 @@ namespace Flow.Launcher.ViewModel
{
lastHistoryIndex = 1;
- // Trick for no delay
- //MainWindowOpacity = 0;
-
if (ExternalPreviewVisible)
CloseExternalPreview();
@@ -1433,6 +1430,24 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
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 0414/1697] 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 ce3f1ac6d..4d8bf76b7 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -72,15 +72,20 @@ namespace Flow.Launcher.Core.Plugin
{
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 @@ namespace Flow.Launcher.Core.Plugin
}
}
- 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 0415/1697] 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 588acbdf8..19f928621 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -309,6 +309,18 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
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 b96cb661e..44850e94e 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 0416/1697] 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 d9b39eb89..da4231f74 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 0417/1697] 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 4d8bf76b7..456f0a699 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -469,10 +469,10 @@ namespace Flow.Launcher.Core.Plugin
/// 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 @@ namespace Flow.Launcher.Core.Plugin
///
/// 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 @@ namespace Flow.Launcher.Core.Plugin
}
}
- 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 f4c8a66da..07bbfdaa0 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -341,7 +341,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
}
else
{
- PluginManager.UpdatePlugin(x.PluginExistingMetadata, x.PluginNewUserPlugin,
+ await PluginManager.UpdatePluginAsync(x.PluginExistingMetadata, x.PluginNewUserPlugin,
downloadToFilePath);
if (Settings.AutoRestartAfterChanging)
@@ -433,7 +433,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
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 @@ namespace Flow.Launcher.Plugin.PluginsManager
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 @@ namespace Flow.Launcher.Plugin.PluginsManager
MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
Context.API.HideMainWindow();
- Uninstall(x.Metadata);
+ await UninstallAsync(x.Metadata);
if (Settings.AutoRestartAfterChanging)
{
Context.API.RestartApp();
@@ -729,7 +729,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
return Search(results, search);
}
- private void Uninstall(PluginMetadata plugin)
+ private async Task UninstallAsync(PluginMetadata plugin)
{
try
{
@@ -737,7 +737,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
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 0418/1697] 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 19f928621..fc8a9f192 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -566,11 +566,14 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
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 44850e94e..9df935b8d 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 0419/1697] 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 456f0a699..76d83cbcf 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -577,7 +577,7 @@ namespace Flow.Launcher.Core.Plugin
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 0420/1697] Add new sponsor to README
---
README.md | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 02ffc7932..6611f55dc 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 0421/1697] 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 edf1da05e..c4e56e813 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -140,6 +140,7 @@ namespace Flow.Launcher.Core.Resource
if (mainWindowSrc == null)
return;
+
ParameterTypes.MARGINS margins = new ParameterTypes.MARGINS();
margins.cxLeftWidth = -1;
margins.cxRightWidth = -1;
@@ -153,8 +154,7 @@ namespace Flow.Launcher.Core.Resource
//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 @@ namespace Flow.Launcher.Core.Resource
{
AutoDropShadow();
}
+
}
public void AutoDropShadow()
@@ -248,6 +249,7 @@ namespace Flow.Launcher.Core.Resource
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 @@ namespace Flow.Launcher.Core.Resource
//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 fc8a9f192..4757b1fb4 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -815,12 +815,23 @@ namespace Flow.Launcher
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 a8b04d640..3d8792a08 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 3249fd221..6b225ae06 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1402,22 +1402,22 @@ namespace Flow.Launcher.ViewModel
{
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 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
mainWindow.SearchIcon.UpdateLayout();
}, DispatcherPriority.Render);
- await Task.Delay(10); // UI 반영 대기
+ //await Task.Delay(10); // UI 반영 대기
}
// 📌 텍스트 초기화 즉시 적용 + UI 강제 업데이트
@@ -1478,23 +1478,22 @@ namespace Flow.Launcher.ViewModel
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 0422/1697] Revert Startup Blinking
---
Flow.Launcher.Core/Resource/Theme.cs | 3 ++-
Flow.Launcher/MainWindow.xaml.cs | 15 ++++++++-------
Flow.Launcher/Themes/Pink.xaml | 2 +-
3 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs
index c4e56e813..3fb4ea1d6 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -154,7 +154,8 @@ namespace Flow.Launcher.Core.Resource
//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 4757b1fb4..75c851ab3 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -819,18 +819,19 @@ namespace Flow.Launcher
if (_settings.HideOnStartup)
{
// 📌 최초 실행 시 창이 깜빡이는 문제 방지 (완전히 숨긴 상태로 시작)
- System.Windows.Application.Current.MainWindow.Visibility = Visibility.Hidden;
+ //System.Windows.Application.Current.MainWindow.Visibility = Visibility.Hidden;
- Dispatcher.BeginInvoke((Action)(() =>
- {
- _viewModel.Hide();
- System.Windows.Application.Current.MainWindow.Visibility = Visibility.Collapsed;
- }), DispatcherPriority.Background);
+ //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 3d8792a08..90592bb99 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 0460/1697] 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 3ca8e163a..75c513411 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 0461/1697] 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 2ead21cf5..a3f87cd30 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 0462/1697] 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 17838ed87..1275570c6 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 e4349cf56..ec068cb5c 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 0463/1697] 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 2aebebd6f..8bcfd9715 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 0464/1697] 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 03b563c9b..098e668cb 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 @@ namespace Flow.Launcher.Plugin.ProcessKiller
{
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 7fa794755..13bf27932 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 d8873bc20..5f58dc6b1 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 @@ namespace Flow.Launcher.Plugin.ProcessKiller
///
/// 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 @@ namespace Flow.Launcher.Plugin.ProcessKiller
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 0465/1697] 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 b97c096c3..1085cc833 100644
--- a/Flow.Launcher.Infrastructure/FileExplorerHelper.cs
+++ b/Flow.Launcher.Infrastructure/FileExplorerHelper.cs
@@ -67,8 +67,6 @@ namespace Flow.Launcher.Infrastructure
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 5f58dc6b1..c603fba09 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs
@@ -68,7 +68,7 @@ namespace Flow.Launcher.Plugin.ProcessKiller
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 0466/1697] 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 098e668cb..aec607575 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs
@@ -91,9 +91,8 @@ namespace Flow.Launcher.Plugin.ProcessKiller
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 @@ namespace Flow.Launcher.Plugin.ProcessKiller
{
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 0467/1697] 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 28747cc7c..05687701d 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -28,8 +28,12 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 0468/1697] 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 38619cbbc..e67b4e5c5 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 @@ namespace Flow.Launcher.Plugin.Sys
{
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 @@ namespace Flow.Launcher.Plugin.Sys
{
_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 0469/1697] 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 a2538893b..e07e30cb2 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 0470/1697] 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 000000000..84f5f046f
--- /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 2a266f8f6..e1d83fa38 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 05687701d..ef9da2719 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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 000000000..f39e6d65f
--- /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 000000000..0755dffa9
--- /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 f806900de..67e840e53 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 feb30821a..539801a0b 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 @@ namespace Flow.Launcher.Plugin.Sys
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 0471/1697] 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 84f5f046f..6c3a99f3e 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Command.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Command.cs
@@ -6,12 +6,39 @@ namespace Flow.Launcher.Plugin.Sys
{
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 000000000..a848f2f1f
--- /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 000000000..8797bf220
--- /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 e1d83fa38..ad3f8553b 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 ef9da2719..fd72ddcaf 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 @@ namespace Flow.Launcher.Plugin.Sys
};
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 @@ namespace Flow.Launcher.Plugin.Sys
return "Title Not Found";
}
- return context.API.GetTranslation(translationKey);
+ return _context.API.GetTranslation(translationKey);
}
private string GetDescription(string key)
@@ -110,7 +112,7 @@ namespace Flow.Launcher.Plugin.Sys
return "Description Not Found";
}
- return context.API.GetTranslation(translationKey);
+ return _context.API.GetTranslation(translationKey);
}
[Obsolete]
@@ -122,7 +124,7 @@ namespace Flow.Launcher.Plugin.Sys
return "Title Not Found";
}
- var translatedTitle = context.API.GetTranslation(translationKey);
+ var translatedTitle = _context.API.GetTranslation(translationKey);
if (query == null)
{
@@ -142,10 +144,10 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 539801a0b..0a38fda04 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 @@ namespace Flow.Launcher.Plugin.Sys
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 0472/1697] 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 fd72ddcaf..5a2505769 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
new Result
{
Title = "Exit",
- SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_exit"),
IcoPath = "Images\\app.png",
Action = c =>
{
@@ -398,7 +357,6 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
new Result
{
Title = "Restart Flow Launcher",
- SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_restart"),
IcoPath = "Images\\app.png",
Action = c =>
{
@@ -422,7 +379,6 @@ namespace Flow.Launcher.Plugin.Sys
new Result
{
Title = "Settings",
- SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_setting"),
IcoPath = "Images\\app.png",
Action = c =>
{
@@ -433,7 +389,6 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 0473/1697] 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 5a2505769..d716484bb 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -78,7 +78,23 @@ namespace Flow.Launcher.Plugin.Sys
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 0474/1697] Fix UI thread issue and preview
---
Flow.Launcher.Core/Resource/Theme.cs | 527 +++++++-----------
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, 234 insertions(+), 330 deletions(-)
diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs
index 36b63a9c2..da3f9f708 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -132,50 +132,64 @@ namespace Flow.Launcher.Core.Resource
=> 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;
-
- HwndSource mainWindowSrc = HwndSource.FromHwnd(mainWindowPtr);
- if (mainWindowSrc == null)
- return;
-
- 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);
-
- // The timing of adding the shadow effect should vary depending on whether the theme is transparent.
- if (BlurEnabled)
+ Application.Current.Dispatcher.Invoke(() =>
{
- AutoDropShadow();
- }
- SetBlurForWindow();
+ System.Windows.Window mainWindow = Application.Current.MainWindow;
+ if (mainWindow == null)
+ return;
- if (!BlurEnabled)
- {
- AutoDropShadow();
- }
+ IntPtr mainWindowPtr = new WindowInteropHelper(mainWindow).Handle;
+ if (mainWindowPtr == IntPtr.Zero)
+ return;
+
+ HwndSource mainWindowSrc = HwndSource.FromHwnd(mainWindowPtr);
+ if (mainWindowSrc == null)
+ return;
+
+ 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);
+
+ // 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 @@ namespace Flow.Launcher.Core.Resource
}
else
{
- RemoveDropShadowEffectFromCurrentTheme();
+ //RemoveDropShadowEffectFromCurrentTheme();
if (BlurEnabled)
{
SetWindowCornerPreference("Default");
@@ -202,108 +216,130 @@ namespace Flow.Launcher.Core.Resource
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,
- };
+ System.Windows.Window mainWindow = GetMainWindow();
+ if (mainWindow == null)
+ return;
- SetWindowCornerPreference(mainWindow, preference);
- }
-
- 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
- {
- SetWindowCornerPreference(mainWindow, DWM_WINDOW_CORNER_PREFERENCE.Default);
-
- }
+ }, DispatcherPriority.Normal);
}
+
+ public void SetCornerForWindow()
+ {
+ Application.Current.Dispatcher.Invoke(() =>
+ {
+ 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)
- };
+ var dict = GetThemeResourceDictionary(_settings.Theme);
+ if (dict == null)
+ return;
- Debug.WriteLine("~~~~~~~~~~~~~~~~~~~~");
- Debug.WriteLine($"Backdrop Mode: {BlurMode()}, DWM Value: {backdropValue}");
+ 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 @@ namespace Flow.Launcher.Core.Resource
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)));
-
- // ✅ 새 스타일을 `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));
- Application.Current.Resources["PreviewWindowBorderStyle"] = defaultStyle;
- }
+ // 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)));
+
+ // 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"] = 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
+ Application.Current.Dispatcher.Invoke(() =>
{
- lightBG = dict.Contains("lightBG") ? (Color)dict["lightBG"] : GetWindowBorderStyleBackground();
- }
- catch (Exception)
- {
- // 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;
- if (colorScheme == "System")
+ Color LightBG;
+ Color DarkBG;
+
+ // 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();
+ }
+ catch (Exception)
+ {
+ LightBG = GetWindowBorderStyleBackground();
+ }
+
+ // DarkBG 값 가져오기 (없으면 LightBG 사용)
+ try
+ {
+ DarkBG = dict.Contains("DarkBG") ? (Color)dict["DarkBG"] : LightBG;
+ }
+ catch (Exception)
+ {
+ DarkBG = LightBG;
+ }
+
+ // ✅ 설정의 ColorScheme을 우선 사용
+ int themeValue = (int)Registry.GetValue(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize", "AppsUseLightTheme", 1);
+ bool isSystemDark = themeValue == 0;
+ bool useDarkMode = Mode == "Dark" || (Mode == "Auto" && _settings.ColorScheme == "System" && isSystemDark) || (_settings.ColorScheme == "Dark");
+
+ Color selectedBG = useDarkMode ? DarkBG : LightBG;
+ ApplyPreviewBackground(selectedBG);
+
+ // ✅ Windows 10 테마(HasBlur=False)는 mainWindow.Background를 설정하지 않음
+ if (!hasBlur)
+ {
+ mainWindow.Background = Brushes.Transparent;
}
else
{
- if (colorScheme == "Dark")
+ // ✅ 블러 테마일 경우만 배경을 투명하게 설정
+ if (_settings.BackdropType == BackdropTypes.Mica || _settings.BackdropType == BackdropTypes.MicaAlt)
{
- 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;
- }
- }
- }
- 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
- }
-
- 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.
-
- if (colorScheme == "System")
- {
- 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 = new SolidColorBrush(selectedBG);
}
}
- else
- {
- if (colorScheme == "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 (colorScheme == "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 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 @@ namespace Flow.Launcher.Core.Resource
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 37f8e6262..9f8063a87 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -193,6 +193,7 @@ namespace Flow.Launcher
{
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 5c668d5ab..2f8332684 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
@@ -41,7 +41,7 @@ public partial class SettingsPaneThemeViewModel : BaseModel
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 f4d5f9908..99cd9af0e 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 0495/1697] - 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 90592bb99..d7de4e246 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 0496/1697] 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 6836d9b3a..1d4a26101 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -62,7 +62,7 @@ namespace Flow.Launcher
DataObject.AddPastingHandler(QueryTextBox, OnPaste);
- this.Loaded += (_, _) =>
+ Loaded += (_, _) =>
{
var handle = new WindowInteropHelper(this).Handle;
var win = HwndSource.FromHwnd(handle);
@@ -70,11 +70,6 @@ namespace Flow.Launcher
};
}
- 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 0497/1697] 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 93f6db111..66da9f59a 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -275,6 +275,9 @@ namespace Flow.Launcher.Infrastructure.UserSettings
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 1e305d3d9..d4508ad67 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 3616e4c59..2f1b2ce66 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -5,7 +5,6 @@ using System.Windows;
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 DataObject = System.Windows.DataObject;
using System.Windows.Media;
using System.Windows.Interop;
using Windows.Win32;
+using System.Reactive.Linq;
namespace Flow.Launcher
{
@@ -68,6 +68,7 @@ namespace Flow.Launcher
var handle = new WindowInteropHelper(this).Handle;
var win = HwndSource.FromHwnd(handle);
win.AddHook(WndProc);
+ SetupSearchTextBoxReactiveness(_settings.SearchQueryResultsWithDelay);
};
}
@@ -204,63 +205,63 @@ namespace Flow.Launcher
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)
+ 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();
+ }
+ 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 @@ namespace Flow.Launcher
{
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 @@ namespace Flow.Launcher
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 6b0144a03..373ecdece 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -569,7 +569,6 @@ namespace Flow.Launcher.ViewModel
{
_queryText = value;
OnPropertyChanged();
- Query();
}
}
@@ -631,6 +630,7 @@ namespace Flow.Launcher.ViewModel
{
// 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 @@ namespace Flow.Launcher.ViewModel
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 0498/1697] 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 66da9f59a..97ee49ef2 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -276,7 +276,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
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 a3f87cd30..454dffd24 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 2f1b2ce66..9e7b380ed 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -865,7 +865,7 @@ namespace Flow.Launcher
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 de4f158ad..72bdb609b 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -139,6 +139,22 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
}
}
+ 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 a80e618e8..986e822e2 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 0499/1697] 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 454dffd24..2426d90af 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 0500/1697] 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 ed031c939..25cc8e878 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 8fe84588f..b9f65ce96 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 99cd9af0e..4cd8408fa 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 d1abbe978..7d2614be8 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 0504/1697] 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 a7dc8c1d1..06e19e051 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -68,7 +68,6 @@ namespace Flow.Launcher
var handle = new WindowInteropHelper(this).Handle;
var win = HwndSource.FromHwnd(handle);
win.AddHook(WndProc);
- SetupSearchTextBoxReactiveness(_settings.SearchQueryResultsWithDelay);
};
}
@@ -196,6 +195,8 @@ namespace Flow.Launcher
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 0505/1697] - 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 0dd1d5bbb..1ae755bd1 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -396,19 +396,26 @@ namespace Flow.Launcher.Core.Resource
// 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 @@ namespace Flow.Launcher.Core.Resource
}, 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 dc9beec1c..87f5ed922 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
@@ -134,10 +134,8 @@ public partial class SettingsPaneThemeViewModel : BaseModel
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 4cd8408fa..9f7e6f5b0 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 0e2f0e245..c45827074 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 e5f310c5a..8bf1f06e2 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 0710/1697] 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 2bfc9587c..192f8b481 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -638,8 +638,13 @@ namespace Flow.Launcher.ViewModel
///
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 @@ namespace Flow.Launcher.ViewModel
}
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 0711/1697] 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 25d9c5d2d..89d4f0847 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -161,24 +161,67 @@ namespace Flow.Launcher
{
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 @@ namespace Flow.Launcher
Dispatcher.Invoke(() => QueryTextBox.CaretIndex = QueryTextBox.Text.Length);
_viewModel.QueryTextCursorMovedToEnd = false;
}
-
break;
case nameof(MainViewModel.GameModeStatus):
_notifyIcon.Icon = _viewModel.GameModeStatus
@@ -280,8 +322,8 @@ namespace Flow.Launcher
_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 @@ namespace Flow.Launcher
// 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 @@ namespace Flow.Launcher
{
_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 192f8b481..9e63244f4 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -10,7 +10,6 @@ using System.Threading.Tasks;
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 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
#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 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
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 0712/1697] 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 89d4f0847..a44b3a305 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -101,11 +101,16 @@ namespace Flow.Launcher
// 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 @@ namespace Flow.Launcher
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 0713/1697] 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 a44b3a305..9eb1271ec 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -948,6 +948,7 @@ namespace Flow.Launcher
ClockPanel.BeginAnimation(OpacityProperty, fadeOut);
}
+
// ✅ 4. When showing ClockPanel (apply fade-in animation)
else if (shouldShowClock && ClockPanel.Visibility != Visibility.Visible && !_isClockPanelAnimating)
{
@@ -971,7 +972,6 @@ namespace Flow.Launcher
}
}
-
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 0714/1697] 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 9eb1271ec..7b3814c87 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -296,7 +296,8 @@ namespace Flow.Launcher
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 0715/1697] 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 833c63ddf..1270d16bf 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -138,13 +138,13 @@ namespace Flow.Launcher
{
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 0716/1697] 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 9e63244f4..6bfde42c5 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -212,7 +212,8 @@ namespace Flow.Launcher.ViewModel
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 0717/1697] 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 1270d16bf..833c63ddf 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -138,13 +138,13 @@ namespace Flow.Launcher
{
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 0718/1697] 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 087b2e998..34b376cc9 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 6bfde42c5..1631ff7c3 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -760,7 +760,10 @@ namespace Flow.Launcher.ViewModel
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 0719/1697] 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 7b3814c87..86b65386e 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -166,22 +166,6 @@ namespace Flow.Launcher
{
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 @@ namespace Flow.Launcher
// 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 @@ namespace Flow.Launcher
_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 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
}
// ✅ 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 1631ff7c3..18ee2cb5b 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -10,6 +10,7 @@ using System.Threading.Tasks;
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 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
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 0720/1697] 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 34b376cc9..533819d17 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 18ee2cb5b..c69fc4484 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -753,8 +753,7 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
// 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 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
}
}, DispatcherPriority.Render);
+ // Switch keyboard layout
if (StartWithEnglishMode)
{
Win32Helper.RestorePreviousKeyboardLayout();
@@ -1558,7 +1562,6 @@ namespace Flow.Launcher.ViewModel
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 0721/1697] Code quality
---
Flow.Launcher/MainWindow.xaml.cs | 47 ++++++++++++++++++--------------
1 file changed, 27 insertions(+), 20 deletions(-)
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 86b65386e..d8c05971a 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -241,7 +241,7 @@ namespace Flow.Launcher
};
// 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 @@ namespace Flow.Launcher
_viewModel.LoadContextMenuCommand.Execute(null);
e.Handled = true;
}
-
break;
case Key.Left:
if (!_viewModel.QueryResultsSelected() && QueryTextBox.CaretIndex == 0)
@@ -359,7 +358,6 @@ namespace Flow.Launcher
_viewModel.EscCommand.Execute(null);
e.Handled = true;
}
-
break;
case Key.Back:
if (specialKeyState.CtrlPressed)
@@ -378,7 +376,6 @@ namespace Flow.Launcher
}
}
}
-
break;
default:
break;
@@ -864,8 +861,11 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
}
// ✅ 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 @@ namespace Flow.Launcher
}
// ✅ 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;
- fadeIn.Completed += (s, e) => _isClockPanelAnimating = false;
- ClockPanel.BeginAnimation(OpacityProperty, fadeIn);
- }, DispatcherPriority.Render);
+ 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 @@ namespace Flow.Launcher
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 0722/1697] 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 d8c05971a..0fd802f1e 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -111,8 +111,8 @@ namespace Flow.Launcher
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 0723/1697] - 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 f1ebba080..ec089b378 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 12b35971d..aa6da9fb2 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 67ba9e391..4c3bd1d12 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 b292657e6..35d1f9a41 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 2bef19373..143d036af 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 c45827074..47e2b0720 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 8bf1f06e2..fdc3a9b45 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 46f2a91ec..59f7adb49 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 f1c8ba192..b59d577f7 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 0725/1697] 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 143d036af..b68641984 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 0729/1697] 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 63debfb47..38c4fbe11 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -113,6 +113,17 @@ namespace Flow.Launcher.Infrastructure.UserSettings
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 f0454b496..f4e2d88af 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 533819d17..b9e355e2f 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 614237146..5b92ee9b9 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 0730/1697] 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 38c4fbe11..cae5d977f 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -113,7 +113,18 @@ namespace Flow.Launcher.Infrastructure.UserSettings
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 f4e2d88af..656431e78 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 85eff3a57..097ce7df4 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -115,6 +115,9 @@ namespace Flow.Launcher
welcomeWindow.Show();
}
+ // Initialize resize mode
+ SetupResizeMode();
+
// Initialize place holder
SetupPlaceholderText();
@@ -243,6 +246,9 @@ namespace Flow.Launcher
case nameof(Settings.ShowPlaceholder):
SetupPlaceholderText();
break;
+ case nameof(Settings.ResizeWindow):
+ SetupResizeMode();
+ break;
}
};
@@ -1071,6 +1077,15 @@ namespace Flow.Launcher
#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 6e83d487a..9c32e9bb9 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
@@ -259,6 +259,12 @@ public partial class SettingsPaneThemeViewModel : BaseModel
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 5b92ee9b9..3abf46f09 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 0731/1697] 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 489002617..44802aa91 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -24,7 +24,7 @@ namespace Flow.Launcher.Core.Resource
{
#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 @@ namespace Flow.Launcher.Core.Resource
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 @@ namespace Flow.Launcher.Core.Resource
var effectSetter = new Setter
{
- Property = Border.EffectProperty,
+ Property = UIElement.EffectProperty,
Value = new DropShadowEffect
{
Opacity = 0.3,
@@ -473,12 +475,12 @@ namespace Flow.Launcher.Core.Resource
}
};
- 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 @@ namespace Flow.Launcher.Core.Resource
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 @@ namespace Flow.Launcher.Core.Resource
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 @@ namespace Flow.Launcher.Core.Resource
{
AutoDropShadow(useDropShadowEffect);
}
- }, DispatcherPriority.Normal);
+ }, DispatcherPriority.Render);
}
///
@@ -596,7 +611,7 @@ namespace Flow.Launcher.Core.Resource
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 097ce7df4..ce34aef1f 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -11,6 +11,7 @@ using System.Windows.Interop;
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 @@ namespace Flow.Launcher
welcomeWindow.Show();
}
- // Initialize resize mode
- SetupResizeMode();
-
// Initialize place holder
SetupPlaceholderText();
@@ -152,13 +150,17 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
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 0732/1697] 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 3cbe8319a..000000000
--- 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 833c63ddf..7b1d113fb 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -177,7 +177,6 @@ namespace Flow.Launcher
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 0733/1697] 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 cae5d977f..7c747ae36 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -134,6 +134,16 @@ namespace Flow.Launcher.Infrastructure.UserSettings
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 656431e78..a9c5ab49f 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 b9e355e2f..82ac63b7d 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 3abf46f09..462ea799e 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 c69fc4484..ec5b52c9d 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -765,6 +765,24 @@ namespace Flow.Launcher.ViewModel
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 0734/1697] Integrate resize window to fixed window height
---
Flow.Launcher.Core/Resource/Theme.cs | 10 ++--
.../UserSettings/Settings.cs | 58 +++++++++++--------
Flow.Launcher/Languages/en.xaml | 6 +-
Flow.Launcher/MainWindow.xaml.cs | 6 +-
.../ViewModels/SettingsPaneThemeViewModel.cs | 6 --
.../SettingPages/Views/SettingsPaneTheme.xaml | 22 +++----
6 files changed, 52 insertions(+), 56 deletions(-)
diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs
index 44802aa91..a1b2c3e0e 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -531,15 +531,15 @@ namespace Flow.Launcher.Core.Resource
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 @@ namespace Flow.Launcher.Core.Resource
}
// 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 7c747ae36..bd146f49a 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -68,11 +68,12 @@ namespace Flow.Launcher.Infrastructure.UserSettings
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 @@ namespace Flow.Launcher.Infrastructure.UserSettings
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 @@ namespace Flow.Launcher.Infrastructure.UserSettings
get => _placeholderText;
set
{
- _placeholderText = value;
- OnPropertyChanged();
+ if (_placeholderText != value)
+ {
+ _placeholderText = value;
+ OnPropertyChanged();
+ }
}
}
@@ -273,10 +269,26 @@ namespace Flow.Launcher.Infrastructure.UserSettings
///
public double CustomWindowTop { get; set; } = 0;
- public bool KeepMaxResults { get; set; } = false;
- public int MaxResultsToShow { get; set; } = 5;
- public int ActivateTimes { get; set; }
+ ///
+ /// 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 ObservableCollection CustomPluginHotkeys { get; set; } = new ObservableCollection();
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index a9c5ab49f..6d890dfba 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 6ffc010a6..3f0dcc3e1 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -252,7 +252,7 @@ namespace Flow.Launcher
case nameof(Settings.PlaceholderText):
_viewModel.PlaceholderText = _settings.PlaceholderText;
break;
- case nameof(Settings.ResizeWindow):
+ case nameof(Settings.KeepMaxResults):
SetupResizeMode();
break;
}
@@ -1087,10 +1087,10 @@ namespace Flow.Launcher
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 64fe351fa..099be496b 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
@@ -259,12 +259,6 @@ public partial class SettingsPaneThemeViewModel : BaseModel
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 462ea799e..f9eef8924 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 0735/1697] 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 82ac63b7d..2e6133df0 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 3f0dcc3e1..5df1b318f 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -455,23 +455,25 @@ namespace Flow.Launcher
{
_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 @@ namespace Flow.Launcher
}
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 0736/1697] 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 ec5b52c9d..a8425a456 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -768,17 +768,10 @@ namespace Flow.Launcher.ViewModel
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 0737/1697] 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 6d890dfba..c170c44e4 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 099be496b..e35c978ed 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
@@ -265,6 +265,11 @@ public partial class SettingsPaneThemeViewModel : BaseModel
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 f9eef8924..5e1ba24ea 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 0738/1697] 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 2e6133df0..82ac63b7d 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 a8425a456..56de70b47 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -584,7 +584,7 @@ namespace Flow.Launcher.ViewModel
[RelayCommand]
private void IncreaseWidth()
{
- Settings.WindowSize += 100;
+ MainWindowWidth += 100;
Settings.WindowLeft -= 50;
OnPropertyChanged(nameof(MainWindowWidth));
}
@@ -592,14 +592,14 @@ namespace Flow.Launcher.ViewModel
[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 0739/1697] 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 9e39ee5bd..fb88da313 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 f1c8ba192..ffecf3fcb 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 d7de4e246..5bbfa26d6 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 0740/1697] 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 a1b2c3e0e..a4cca2a1d 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -531,7 +531,7 @@ namespace Flow.Launcher.Core.Resource
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 0741/1697] 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 a4cca2a1d..e5980b62f 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -565,7 +565,7 @@ namespace Flow.Launcher.Core.Resource
}
// 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 5df1b318f..8f22d64b8 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -1097,7 +1097,7 @@ namespace Flow.Launcher
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 0742/1697] - Fix Preview in WelcomePage - Adjust BG Color -
Fix aspect ratio wallpaper bitmap
---
.../Helper/WallpaperPathRetrieval.cs | 105 +++++++++++-------
.../Resources/Pages/WelcomePage1.xaml | 4 +-
.../Resources/Pages/WelcomePage2.xaml | 2 +-
.../Resources/Pages/WelcomePage5.xaml | 6 +-
4 files changed, 72 insertions(+), 45 deletions(-)
diff --git a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
index 151ce97dd..47a77f398 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 class WallpaperPathRetrieval
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;
- }
-
- // 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)
- {
- // 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;
+ App.API.LogInfo(nameof(WallpaperPathRetrieval), $"Wallpaper path is invalid: {wallpaperPath}");
+ var wallpaperColor = GetWallpaperColor();
+ return new SolidColorBrush(wallpaperColor);
}
- 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);
+
+ // 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)
+ {
+ wallpaperCache.Remove(oldestCache);
+ }
+ }
+
+ wallpaperCache.Add((wallpaperPath, dateModified), wallpaperBrush);
+ return wallpaperBrush;
+
}
catch (Exception ex)
{
@@ -86,8 +112,9 @@ public static class WallpaperPathRetrieval
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 1728195bd..32fdb62fc 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 04c76d027..f62cec3bf 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 c898ac9a0..3df4b506e 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 0743/1697] Code quality & Lock & Bitmap memory & Registry
access improvement
---
.../Helper/WallpaperPathRetrieval.cs | 75 +++++++++----------
1 file changed, 37 insertions(+), 38 deletions(-)
diff --git a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
index 47a77f398..77bebe2d3 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 class WallpaperPathRetrieval
// 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;
+ }
}
+
+ 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;
- // 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)
+ 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 class WallpaperPathRetrieval
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 class WallpaperPathRetrieval
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 @@ public static class WallpaperPathRetrieval
}
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 0744/1697] 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 600b9e9dc..24c7bd65b 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 5a9bc2595..59ebad0f6 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 55f1dacc0..9ffaaf566 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 eb8cc9557..6e3510f79 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 000000000..5889a1280
--- /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 15a814436..c8c119e94 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 class DropdownDataGeneric : BaseModel where TValue : Enum
{
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 4a729b578..909011579 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -150,7 +150,7 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
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 e63336235..7ca776512 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 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
OnPropertyChanged(nameof(ActionKeywordsText));
}
+ public void OnSearchDelaySpeedChanged()
+ {
+ OnPropertyChanged(nameof(SearchDelaySpeedText));
+ }
+
public void ChangePriority(int newPriority)
{
PluginPair.Metadata.Priority = newPriority;
@@ -180,8 +187,8 @@ namespace Flow.Launcher.ViewModel
[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 0772/1697] 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 ab0a364d2..fed4b667b 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -320,28 +320,10 @@ namespace Flow.Launcher.Infrastructure.UserSettings
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 0773/1697] 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 5889a1280..cfbde8be2 100644
--- a/Flow.Launcher/SearchDelaySpeedWindow.xaml.cs
+++ b/Flow.Launcher/SearchDelaySpeedWindow.xaml.cs
@@ -28,7 +28,7 @@ public partial class SearchDelaySpeedWindow : Window
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 309cd67bb..f43931192 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -298,7 +298,7 @@ namespace Flow.Launcher.ViewModel
{
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 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
}
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 0774/1697] 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 d1c047495..da92a3583 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/PluginSettings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/PluginSettings.cs
@@ -51,7 +51,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
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 @@ namespace Flow.Launcher.Infrastructure.UserSettings
}
metadata.Disabled = settings.Disabled;
metadata.Priority = settings.Priority;
- metadata.SearchDelaySpeed = settings.SearchDelaySpeed;
+ metadata.SearchDelayTime = settings.SearchDelayTime;
}
else
{
@@ -80,8 +80,8 @@ namespace Flow.Launcher.Infrastructure.UserSettings
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 @@ namespace Flow.Launcher.Infrastructure.UserSettings
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 fed4b667b..fcfbe8ca0 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -323,7 +323,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
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 42b623717..1496765ce 100644
--- a/Flow.Launcher.Plugin/PluginMetadata.cs
+++ b/Flow.Launcher.Plugin/PluginMetadata.cs
@@ -99,10 +99,10 @@ namespace Flow.Launcher.Plugin
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 543f8b3f6..000000000
--- 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 000000000..8dae5997e
--- /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 ae930db70..e6a764d48 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 bd2f9a7c9..0fd98bfac 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 1813ff6ab..21ecd39c0 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 @@ public partial class SearchDelaySpeedWindow : Window
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 909011579..3262ad208 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -31,7 +31,7 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
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 partial class SettingsPaneGeneralViewModel : BaseModel
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 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
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 372fdccd7..2b198474b 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 f43931192..283e26b95 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1271,14 +1271,13 @@ namespace Flow.Launcher.ViewModel
{
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 7ca776512..76e212c1d 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 @@ namespace Flow.Launcher.ViewModel
}
}
- 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 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
OnPropertyChanged(nameof(ActionKeywordsText));
}
- public void OnSearchDelaySpeedChanged()
+ public void OnSearchDelayTimeChanged()
{
- OnPropertyChanged(nameof(SearchDelaySpeedText));
+ OnPropertyChanged(nameof(SearchDelayTimeText));
}
public void ChangePriority(int newPriority)
@@ -185,10 +183,10 @@ namespace Flow.Launcher.ViewModel
}
[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 f81590092..e27426133 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 0775/1697] 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 0776/1697] 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 8bde5eb33..1372e0993 100644
--- a/Flow.Launcher/SearchDelayTimeWindow.xaml.cs
+++ b/Flow.Launcher/SearchDelayTimeWindow.xaml.cs
@@ -28,7 +28,7 @@ public partial class SearchDelayTimeWindow : Window
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 0777/1697] 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 76e212c1d..807fd6e85 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -105,7 +105,8 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
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 0778/1697] 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 21ecd39c0..1c7ca58d0 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 @@ public partial class SearchDelayTimeWindow : Window
// 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 @@ public partial class SearchDelayTimeWindow : Window
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 807fd6e85..e91badb38 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -118,7 +118,7 @@ namespace Flow.Launcher.ViewModel
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 0779/1697] 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 7c96fe88d..44b82b372 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 53d70e8d5..6e2488fe1 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 e63567ce5..49306cd2d 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 0780/1697] Improve string resources
---
.../UserSettings/Settings.cs | 2 +-
Flow.Launcher.Plugin/SearchDelayTime.cs | 24 +++++++++----------
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, 25 insertions(+), 25 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index fcfbe8ca0..6cb20d12f 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -323,7 +323,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
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 8dae5997e..ae1daabe0 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.
+ ///
+ VeryLong,
+
+ ///
+ /// Long search delay time. 200ms.
///
Long,
///
- /// Moderately long search delay time. 200ms.
+ /// Normal search delay time. 150ms. Default value.
///
- ModeratelyLong,
+ Normal,
///
- /// Medium search delay time. 150ms. Default value.
+ /// Short search delay time. 100ms.
///
- Medium,
+ Short,
///
- /// Moderately short search delay time. 100ms.
+ /// Very short search delay time. 50ms.
///
- ModeratelyShort,
-
- ///
- /// Short search delay time. 50ms.
- ///
- Short
+ VeryShort
}
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index e6a764d48..364be4009 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 cfd8c5b7e..4a3c9f5a7 100644
--- a/Flow.Launcher/SearchDelayTimeWindow.xaml.cs
+++ b/Flow.Launcher/SearchDelayTimeWindow.xaml.cs
@@ -24,7 +24,7 @@ public partial class SearchDelayTimeWindow : Window
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 3262ad208..cec8c318c 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -150,7 +150,7 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
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 283e26b95..2fc4eaf7c 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1273,11 +1273,11 @@ namespace Flow.Launcher.ViewModel
{
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 e27426133..64681f803 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 0781/1697] 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 24890a363..caedb44c0 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1150,9 +1150,6 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
_ => 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 @@ namespace Flow.Launcher.ViewModel
// 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 0782/1697] 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 caedb44c0..17e4b55b7 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1230,15 +1230,6 @@ namespace Flow.Launcher.ViewModel
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 0783/1697] 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 edb2c1441..3f8272dda 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 0784/1697] 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 b19c668e0..74edd2dea 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 0785/1697] 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 7e9cc9a48..f80e573f9 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 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
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 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
}
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 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
}
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 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
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 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
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 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
var result = dlg.ShowDialog();
return result == DialogResult.OK ? dlg.FileName : string.Empty;
-
}
///
@@ -183,31 +179,33 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
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 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
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 0786/1697] 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 000000000..4757681bc
--- /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 0787/1697] 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 4757681bc..4e4453636 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 74edd2dea..ca9f673d8 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 3c1aba400..5cd14ba7e 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 37079a46f..7580a5591 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 0788/1697] 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 4467b94fb..31faeba52 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
@@ -9,9 +9,13 @@ namespace Flow.Launcher.Plugin.Sys
{
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 @@ namespace Flow.Launcher.Plugin.Sys
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 0789/1697] 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 ca9f673d8..009644fd6 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 0790/1697] 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 009644fd6..cb1d8dbc4 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 000000000..b379b875f
--- /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 000000000..649913872
--- /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 0791/1697] 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 7b1d113fb..9aee56bff 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -138,6 +138,11 @@ namespace Flow.Launcher
{
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 0792/1697] 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 f80e573f9..0bd00d982 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
@@ -69,10 +69,44 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
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 3c0e5b153..2df430c3b 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 0793/1697] Code quality
---
.../Environments/AbstractPluginEnvironment.cs | 4 ++--
.../Environments/PythonEnvironment.cs | 12 ++++++++----
.../Environments/TypeScriptEnvironment.cs | 14 +++++++++-----
.../Environments/TypeScriptV2Environment.cs | 14 +++++++++-----
4 files changed, 28 insertions(+), 16 deletions(-)
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
index 0bd00d982..bbb6cf638 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
@@ -249,8 +249,8 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
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 607c19062..fab5738de 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 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
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 399f7cc03..8a4f527ba 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 Droplex;
-using Flow.Launcher.Infrastructure.UserSettings;
-using Flow.Launcher.Plugin.SharedCommands;
-using Flow.Launcher.Plugin;
using System.IO;
+using Droplex;
using Flow.Launcher.Core.Plugin;
+using Flow.Launcher.Infrastructure.UserSettings;
+using Flow.Launcher.Plugin;
+using Flow.Launcher.Plugin.SharedCommands;
namespace Flow.Launcher.Core.ExternalPlugins.Environments
{
@@ -19,7 +19,11 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
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 e8cb72e11..61fd28376 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 Droplex;
-using Flow.Launcher.Infrastructure.UserSettings;
-using Flow.Launcher.Plugin.SharedCommands;
-using Flow.Launcher.Plugin;
using System.IO;
+using Droplex;
using Flow.Launcher.Core.Plugin;
+using Flow.Launcher.Infrastructure.UserSettings;
+using Flow.Launcher.Plugin;
+using Flow.Launcher.Plugin.SharedCommands;
namespace Flow.Launcher.Core.ExternalPlugins.Environments
{
@@ -19,7 +19,11 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
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 0794/1697] 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 4f869901c..17517832b 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 0795/1697] 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 8df2ce9ed..102d0089f 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 @@ namespace Flow.Launcher.Core.Plugin.JsonRPCV2Models
return _api.GetAllPlugins();
}
-
public MatchResult FuzzySearch(string query, string stringToCompare)
{
return _api.FuzzySearch(query, stringToCompare);
@@ -156,6 +155,11 @@ namespace Flow.Launcher.Core.Plugin.JsonRPCV2Models
_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 9f5d6725e..9e1173f34 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 @@ namespace Flow.Launcher.Infrastructure.Logger
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 f178ebb90..9258e5147 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -227,6 +227,11 @@ namespace Flow.Launcher.Plugin
///
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 e19ad2fdc..31307b668 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -187,6 +187,9 @@ namespace Flow.Launcher
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 0796/1697] 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 31307b668..2d2713e79 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -11,9 +11,9 @@ using System.Threading;
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.SharedModels;
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 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
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 0797/1697] 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 9e1173f34..84331ef70 100644
--- a/Flow.Launcher.Infrastructure/Logger/Log.cs
+++ b/Flow.Launcher.Infrastructure/Logger/Log.cs
@@ -135,6 +135,15 @@ namespace Flow.Launcher.Infrastructure.Logger
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 0798/1697] Add plugin json storage
---
.../Image/ImageLoader.cs | 1 +
.../Storage/BinaryStorage.cs | 62 +++++++++++++++----
.../Storage/PluginBinaryStorage.cs | 15 +++++
.../Storage/PluginJsonStorage.cs | 6 --
4 files changed, 65 insertions(+), 19 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 6f7b1cd90..cca4bd2a4 100644
--- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
@@ -37,6 +37,7 @@ namespace Flow.Launcher.Infrastructure.Image
_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 5b73faae6..69ac6000b 100644
--- a/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs
@@ -4,6 +4,8 @@ using Flow.Launcher.Infrastructure.Logger;
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";
- // Let the derived class to set the file path
- public BinaryStorage(string filename, string directoryPath = null)
- {
- directoryPath ??= DataLocation.CacheDirectory;
- Helper.ValidateDirectory(directoryPath);
+ protected string FilePath { get; init; } = null!;
- FilePath = Path.Combine(directoryPath, $"{filename}{FileSuffix}");
+ protected string DirectoryPath { get; init; } = null!;
+
+ // Let the derived class to set the file path
+ protected BinaryStorage()
+ {
}
- 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 @@ namespace Flow.Launcher.Infrastructure.Storage
try
{
var t = await MemoryPackSerializer.DeserializeAsync(stream);
- return t;
+ return t ?? defaultData;
}
catch (System.Exception)
{
@@ -65,6 +80,27 @@ namespace Flow.Launcher.Infrastructure.Storage
}
}
+ 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 000000000..87f51d5d7
--- /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 b377c81aa..9c6547c66 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 @@ namespace Flow.Launcher.Infrastructure.Storage
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 0799/1697] 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 8df2ce9ed..cf1c57f3e 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs
@@ -185,5 +185,10 @@ namespace Flow.Launcher.Core.Plugin.JsonRPCV2Models
{
_api.StopLoadingBar();
}
+
+ public void SavePluginCaches()
+ {
+ _api.SavePluginCaches();
+ }
}
}
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 4f869901c..fa4e43e07 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -66,6 +66,7 @@ namespace Flow.Launcher.Core.Plugin
}
API.SavePluginSettings();
+ API.SavePluginCaches();
}
public static async ValueTask DisposePluginsAsync()
@@ -587,11 +588,13 @@ namespace Flow.Launcher.Core.Plugin
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 f178ebb90..be776b068 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -344,5 +344,38 @@ namespace Flow.Launcher.Plugin
/// 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 77bd304e4..cabd26962 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 @@ namespace Flow.Launcher.Plugin
///
void Save();
}
-}
\ No newline at end of file
+}
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index e19ad2fdc..17d7e103e 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -236,14 +236,6 @@ namespace Flow.Launcher
((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 @@ namespace Flow.Launcher
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 0800/1697] 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 3be23214c..5bc518105 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -8,7 +8,6 @@ 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;
@@ -19,19 +18,17 @@ using Stopwatch = Flow.Launcher.Infrastructure.Stopwatch;
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 @@ namespace Flow.Launcher.Plugin.Program
{
}
- 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 @@ namespace Flow.Launcher.Plugin.Program
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 @@ namespace Flow.Launcher.Plugin.Program
}
// 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 @@ namespace Flow.Launcher.Plugin.Program
}
}
- 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 @@ namespace Flow.Launcher.Plugin.Program
public Control CreateSettingPanel()
{
- return new ProgramSetting(Context, _settings, _win32s, _uwps);
+ return new ProgramSetting(Context, _settings);
}
public string GetTranslatedPluginTitle()
@@ -370,7 +370,7 @@ namespace Flow.Launcher.Plugin.Program
_settings.DisabledProgramSources.Add(new ProgramSource(program));
_ = Task.Run(() =>
{
- IndexUwpPrograms();
+ _ = IndexUwpProgramsAsync();
});
}
else if (_win32s.Any(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier))
@@ -380,7 +380,7 @@ namespace Flow.Launcher.Plugin.Program
_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 654897cc5..bf100ed7e 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWPPackage.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWPPackage.cs
@@ -317,7 +317,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
{
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 a64a708ef..06be2a628 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs
@@ -797,7 +797,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
{
}
- 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 91864cb68..5ad7fcea3 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 @@ namespace Flow.Launcher.Plugin.Program.Views
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 0801/1697] 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 17d7e103e..770195550 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -201,7 +201,7 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
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 0802/1697] 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 20f905411..07e9fba1e 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
@@ -6,7 +6,6 @@ using System.Threading.Tasks;
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 partial class SettingsPaneAboutViewModel : BaseModel
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 partial class SettingsPaneAboutViewModel : BaseModel
};
public string ActivatedTimes => string.Format(
- InternationalizationManager.Instance.GetTranslation("about_activate_times"),
+ App.API.GetTranslation("about_activate_times"),
_settings.ActivateTimes
);
@@ -88,8 +87,8 @@ public partial class SettingsPaneAboutViewModel : BaseModel
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 @@ public partial class SettingsPaneAboutViewModel : BaseModel
}
[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 0803/1697] 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 2df430c3b..6963d81c9 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 07e9fba1e..47cb1b6c3 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
@@ -27,6 +27,15 @@ public partial class SettingsPaneAboutViewModel : BaseModel
}
}
+ 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 @@ public partial class SettingsPaneAboutViewModel : BaseModel
}
}
+ [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 @@ public partial class SettingsPaneAboutViewModel : BaseModel
App.API.OpenDirectory(parentFolderPath);
}
-
[RelayCommand]
private void OpenLogsFolder()
{
@@ -147,6 +170,30 @@ public partial class SettingsPaneAboutViewModel : BaseModel
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 75c513411..f7deee7cf 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 0804/1697] 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 6963d81c9..f96509bde 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 47cb1b6c3..1cd90e613 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
@@ -103,7 +103,15 @@ public partial class SettingsPaneAboutViewModel : BaseModel
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 @@ public partial class SettingsPaneAboutViewModel : BaseModel
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 @@ public partial class SettingsPaneAboutViewModel : BaseModel
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 0805/1697] 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 f96509bde..24ab3cf94 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 1cd90e613..e0530bb83 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 @@ public partial class SettingsPaneAboutViewModel : BaseModel
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 @@ public partial class SettingsPaneAboutViewModel : BaseModel
if (confirmResult == MessageBoxResult.Yes)
{
- try
+ if (!ClearCacheFolder())
{
- ClearCacheFolder();
- }
- catch (Exception e)
- {
- App.API.LogException(nameof(SettingsPaneAboutViewModel), "Failed to clear cache folder", e);
App.API.ShowMsgBox(App.API.GetTranslation("clearfolderfailMessage"));
}
}
@@ -161,19 +153,45 @@ public partial class SettingsPaneAboutViewModel : BaseModel
[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 @@ public partial class SettingsPaneAboutViewModel : BaseModel
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 0806/1697] 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 e0530bb83..6cfb98306 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
@@ -180,7 +180,7 @@ public partial class SettingsPaneAboutViewModel : BaseModel
{
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 0807/1697] 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 84331ef70..807d631c7 100644
--- a/Flow.Launcher.Infrastructure/Logger/Log.cs
+++ b/Flow.Launcher.Infrastructure/Logger/Log.cs
@@ -135,14 +135,12 @@ namespace Flow.Launcher.Infrastructure.Logger
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 0808/1697] 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 6f7b1cd90..4bd4c29c8 100644
--- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
@@ -277,7 +277,7 @@ namespace Flow.Launcher.Infrastructure.Image
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 @@ namespace Flow.Launcher.Infrastructure.Image
// 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 f178ebb90..fb80ede83 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -8,6 +8,7 @@ using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
+using System.Windows.Media;
namespace Flow.Launcher.Plugin
{
@@ -344,5 +345,20 @@ namespace Flow.Launcher.Plugin
/// 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 e19ad2fdc..d12c6ac3e 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -10,6 +10,7 @@ using System.Runtime.CompilerServices;
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 @@ namespace Flow.Launcher
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 0809/1697] 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 e9b434fd9..3d94769d0 100644
--- a/Flow.Launcher/MessageBoxEx.xaml.cs
+++ b/Flow.Launcher/MessageBoxEx.xaml.cs
@@ -156,7 +156,7 @@ namespace Flow.Launcher
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 94184ff63..ff9accd62 100644
--- a/Flow.Launcher/Msg.xaml.cs
+++ b/Flow.Launcher/Msg.xaml.cs
@@ -43,7 +43,7 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
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 17e4b55b7..bfa5bd504 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1168,7 +1168,7 @@ namespace Flow.Launcher.ViewModel
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 e91badb38..93a595de4 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -45,7 +45,7 @@ namespace Flow.Launcher.ViewModel
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 db124e078..9aab71a32 100644
--- a/Flow.Launcher/ViewModel/ResultViewModel.cs
+++ b/Flow.Launcher/ViewModel/ResultViewModel.cs
@@ -199,7 +199,7 @@ namespace Flow.Launcher.ViewModel
}
}
- 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 0810/1697] 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 878832e4f..aaf1efdc1 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;
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 partial class PreviewPanel : UserControl, INotifyPropertyChanged
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 9c5e81cb5..6554edd83 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 @@ namespace Flow.Launcher.Plugin.WebSearch
#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 @@ namespace Flow.Launcher.Plugin.WebSearch
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 0811/1697] 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 51f81b718..590666af7 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.Linq;
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 @@ namespace Flow.Launcher.Plugin.WebSearch.SuggestionSources
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 @@ namespace Flow.Launcher.Plugin.WebSearch.SuggestionSources
}
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 640674243..938f7d387 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 @@ using System.Threading;
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 @@ namespace Flow.Launcher.Plugin.WebSearch.SuggestionSources
.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 8fafb44cc..1d248caf3 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 @@ namespace Flow.Launcher.Plugin.WebSearch.SuggestionSources
{
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 @@ namespace Flow.Launcher.Plugin.WebSearch.SuggestionSources
}
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 265de4a98..5f2504009 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 @@ namespace Flow.Launcher.Plugin.WebSearch.SuggestionSources
{
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 @@ namespace Flow.Launcher.Plugin.WebSearch.SuggestionSources
}
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 0812/1697] 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 fb80ede83..0ee576b2e 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -348,7 +348,7 @@ namespace Flow.Launcher.Plugin
///
/// 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 0813/1697] 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 938f7d387..9efc36263 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Bing.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Bing.cs
@@ -33,7 +33,7 @@ namespace Flow.Launcher.Plugin.WebSearch.SuggestionSources
}
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 0814/1697] 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 5f2504009..ad8fb508f 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Google.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Google.cs
@@ -27,7 +27,7 @@ namespace Flow.Launcher.Plugin.WebSearch.SuggestionSources
}
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 0815/1697] 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 590666af7..65be06b53 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Baidu.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Baidu.cs
@@ -24,7 +24,7 @@ namespace Flow.Launcher.Plugin.WebSearch.SuggestionSources
}
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 0816/1697] 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 9a77ece32..96efcacf6 100644
--- a/Flow.Launcher.Core/Updater.cs
+++ b/Flow.Launcher.Core/Updater.cs
@@ -17,6 +17,7 @@ using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using System.Text.Json.Serialization;
using System.Threading;
+using System.Text.Json;
namespace Flow.Launcher.Core
{
@@ -51,7 +52,7 @@ namespace Flow.Launcher.Core
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 @@ namespace Flow.Launcher.Core
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 864d796c7..c393c4016 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 @@ namespace Flow.Launcher.Infrastructure
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 0817/1697] 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 c393c4016..b02d84ca7 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 @@ namespace Flow.Launcher.Infrastructure
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 5b73faae6..a8d5f5d62 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 @@ namespace Flow.Launcher.Infrastructure.Storage
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 865041fb3..3669bb405 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 40106acd8..a3488124b 100644
--- a/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
@@ -5,6 +5,7 @@ using System.IO;
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 @@ namespace Flow.Launcher.Infrastructure.Storage
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 b377c81aa..cc78bb8f6 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 @@ namespace Flow.Launcher.Infrastructure.Storage
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 5f003e351..1de5841a5 100644
--- a/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs
+++ b/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs
@@ -318,5 +318,51 @@ namespace Flow.Launcher.Plugin.SharedCommands
{
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 3be23214c..73b4ae9e6 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -6,13 +6,13 @@ using System.Linq;
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 @@ namespace Flow.Launcher.Plugin.Program
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 7ad9715bb..76aeb3250 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Main.cs
@@ -5,7 +5,6 @@ using System.Linq;
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 @@ namespace Flow.Launcher.Plugin.WebSearch
// 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 0818/1697] 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 3468015eb..758ce68ae 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 3b37bbaed..0e02b2c9e 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 @@ public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader
}
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 @@ public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader
}
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 @@ public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader
}
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 @@ public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader
}
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 @@ public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader
}
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 b4e42fbcd..d09b9e750 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 ce7f56c34..5ab868ab9 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 class Main : ISettingProvider, IPlugin, IReloadable, IPluginI18n, IContex
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 0819/1697] 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 8584a3eb0..3182adfed 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 Flow.Launcher.Plugin.BrowserBookmark.Models;
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 partial class SettingsControl : INotifyPropertyChanged
Settings = settings;
InitializeComponent();
}
+
public bool LoadChromeBookmark
{
get => Settings.LoadChromeBookmark;
@@ -62,6 +56,7 @@ public partial class SettingsControl : INotifyPropertyChanged
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 0820/1697] 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 d9c4e91d0..39bbb73ff 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 @@ public abstract class ChromiumBookmarkLoader : IBookmarkLoader
}
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 @@ public abstract class ChromiumBookmarkLoader : IBookmarkLoader
}
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 @@ public abstract class ChromiumBookmarkLoader : IBookmarkLoader
}
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 @@ public abstract class ChromiumBookmarkLoader : IBookmarkLoader
}
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 @@ public abstract class ChromiumBookmarkLoader : IBookmarkLoader
}
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 @@ public abstract class ChromiumBookmarkLoader : IBookmarkLoader
}
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 d09b9e750..49ae26564 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 0821/1697] 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 39bbb73ff..282876472 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 0e02b2c9e..d2f973329 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 5ab868ab9..5dec8b953 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 class Main : ISettingProvider, IPlugin, IReloadable, IPluginI18n, IContex
_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 0822/1697] 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 069154364..4f8287c16 100644
--- a/Flow.Launcher.Core/Configuration/Portable.cs
+++ b/Flow.Launcher.Core/Configuration/Portable.cs
@@ -169,7 +169,7 @@ namespace Flow.Launcher.Core.Configuration
{
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 0823/1697] 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 7a3a0c36e..42461dc18 100644
--- a/Flow.Launcher.Infrastructure/Win32Helper.cs
+++ b/Flow.Launcher.Infrastructure/Win32Helper.cs
@@ -488,5 +488,16 @@ namespace Flow.Launcher.Infrastructure
}
#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 cb1cbb729..23125de15 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 @@ namespace Flow.Launcher
});
}
- [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 0824/1697] 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 9a77ece32..5b2144efe 100644
--- a/Flow.Launcher.Core/Updater.cs
+++ b/Flow.Launcher.Core/Updater.cs
@@ -4,10 +4,11 @@ using System.Net;
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.Http;
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 @@ namespace Flow.Launcher.Core
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 @@ namespace Flow.Launcher.Core
}
// 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 @@ namespace Flow.Launcher.Core
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 0825/1697] 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 4f8287c16..8abdae8d8 100644
--- a/Flow.Launcher.Core/Configuration/Portable.cs
+++ b/Flow.Launcher.Core/Configuration/Portable.cs
@@ -22,7 +22,7 @@ namespace Flow.Launcher.Core.Configuration
/// 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 @@ namespace Flow.Launcher.Core.Configuration
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 @@ namespace Flow.Launcher.Core.Configuration
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 @@ namespace Flow.Launcher.Core.Configuration
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 0826/1697] 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 8abdae8d8..2b570d2c0 100644
--- a/Flow.Launcher.Core/Configuration/Portable.cs
+++ b/Flow.Launcher.Core/Configuration/Portable.cs
@@ -159,7 +159,7 @@ namespace Flow.Launcher.Core.Configuration
{
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 0827/1697] 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 9aee56bff..f484d4dba 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -304,6 +304,14 @@ namespace Flow.Launcher
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 011d46d6b..c62606743 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 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
private async void OnClosing(object sender, CancelEventArgs e)
{
- if (!_canClose)
+ if (!CanClose)
{
_notifyIcon.Visible = false;
App.API.SaveAppAllSettings();
@@ -287,7 +292,7 @@ namespace Flow.Launcher
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 0828/1697] 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 6f7b1cd90..0ba059b7b 100644
--- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
@@ -61,7 +61,7 @@ namespace Flow.Launcher.Infrastructure.Image
});
}
- public static async Task Save()
+ public static async Task SaveAsync()
{
await storageLock.WaitAsync();
@@ -77,6 +77,12 @@ namespace Flow.Launcher.Infrastructure.Image
}
}
+ 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 e19ad2fdc..b86e731b3 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -57,7 +57,7 @@ namespace Flow.Launcher
_mainVM.ChangeQueryText(query, requery);
}
- public void RestartApp()
+ public async void RestartApp()
{
_mainVM.Hide();
@@ -66,6 +66,9 @@ namespace Flow.Launcher
// 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 @@ namespace Flow.Launcher
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 0829/1697] 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 b86e731b3..a9862c74c 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -57,16 +57,18 @@ namespace Flow.Launcher
_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 @@ namespace Flow.Launcher
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 0830/1697] 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 a9862c74c..d88eeb7c9 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -37,6 +37,8 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
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 0831/1697] 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 944b2fd10..e0a217251 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
@@ -23,6 +23,8 @@ namespace Flow.Launcher.Core.Plugin
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 @@ namespace Flow.Launcher.Core.Plugin
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 865041fb3..a3634a0e2 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 @@ namespace Flow.Launcher.Infrastructure.Storage
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 b377c81aa..e02d51bdb 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 @@ namespace Flow.Launcher.Infrastructure.Storage
{
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 0832/1697] 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 0ba059b7b..1ee033821 100644
--- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
@@ -71,6 +71,10 @@ namespace Flow.Launcher.Infrastructure.Image
.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 0833/1697] 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 40106acd8..52bcdcfab 100644
--- a/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
@@ -180,20 +180,24 @@ namespace Flow.Launcher.Infrastructure.Storage
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 0834/1697] 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 52bcdcfab..40106acd8 100644
--- a/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
@@ -180,24 +180,20 @@ namespace Flow.Launcher.Infrastructure.Storage
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 0835/1697] 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 42461dc18..f2b99588d 100644
--- a/Flow.Launcher.Infrastructure/Win32Helper.cs
+++ b/Flow.Launcher.Infrastructure/Win32Helper.cs
@@ -489,8 +489,7 @@ namespace Flow.Launcher.Infrastructure
#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 0836/1697] 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 f2b99588d..5bec3e5e7 100644
--- a/Flow.Launcher.Infrastructure/Win32Helper.cs
+++ b/Flow.Launcher.Infrastructure/Win32Helper.cs
@@ -492,7 +492,7 @@ namespace Flow.Launcher.Infrastructure
#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 0837/1697] 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 5bec3e5e7..d3023a3f0 100644
--- a/Flow.Launcher.Infrastructure/Win32Helper.cs
+++ b/Flow.Launcher.Infrastructure/Win32Helper.cs
@@ -490,6 +490,7 @@ namespace Flow.Launcher.Infrastructure
#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 0838/1697] 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 d3023a3f0..c21849403 100644
--- a/Flow.Launcher.Infrastructure/Win32Helper.cs
+++ b/Flow.Launcher.Infrastructure/Win32Helper.cs
@@ -491,9 +491,9 @@ namespace Flow.Launcher.Infrastructure
#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 0839/1697] 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 23125de15..30b3a0673 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 0840/1697] 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 0fbeed9f5..8b4062b6b 100644
--- a/Flow.Launcher.Infrastructure/Storage/FlowLauncherJsonStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/FlowLauncherJsonStorage.cs
@@ -3,6 +3,7 @@ using System.Threading.Tasks;
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 910672119..e8cbd70fb 100644
--- a/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs
@@ -3,6 +3,7 @@ using System.Threading.Tasks;
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 0841/1697] 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 c33c42889..5a2259ff1 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 156135f81..b333aba42 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 @@ namespace Flow.Launcher.Plugin.PluginsManager
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 79d6aedd5..9cee8bc8f 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 @@ namespace Flow.Launcher.Plugin.PluginsManager
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 @@ namespace Flow.Launcher.Plugin.PluginsManager
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 @@ namespace Flow.Launcher.Plugin.PluginsManager
}
}).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 @@ namespace Flow.Launcher.Plugin.PluginsManager
}
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 @@ namespace Flow.Launcher.Plugin.PluginsManager
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 @@ namespace Flow.Launcher.Plugin.PluginsManager
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 @@ namespace Flow.Launcher.Plugin.PluginsManager
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 @@ namespace Flow.Launcher.Plugin.PluginsManager
{
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 @@ namespace Flow.Launcher.Plugin.PluginsManager
}
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 0842/1697] 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 68be746f2..e9713564e 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 affd7c312..1f23c2f66 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 ac8abcdcc..4f5c4ae40 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 79d6d7605..000000000
--- 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 000000000..5c9189ae1
--- /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 38b5bec65..d1cf74501 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 482e821dc..265657ef4 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 743f5b25b..4bb78f6ff 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 0843/1697] 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 4f5c4ae40..44d3ef0ff 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 @@ namespace Flow.Launcher.Core.ExternalPlugins
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 @@ namespace Flow.Launcher.Core.ExternalPlugins
}
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 9cee8bc8f..9d2a8fe73 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -236,7 +236,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
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 @@ namespace Flow.Launcher.Plugin.PluginsManager
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 0844/1697] 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 f178ebb90..513c2da84 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -344,5 +344,23 @@ namespace Flow.Launcher.Plugin
/// 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 d88eeb7c9..a8ec46982 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -28,6 +28,7 @@ using Flow.Launcher.Plugin.SharedCommands;
using Flow.Launcher.ViewModel;
using JetBrains.Annotations;
using Flow.Launcher.Core.Resource;
+using Flow.Launcher.Core.ExternalPlugins;
namespace Flow.Launcher
{
@@ -354,6 +355,11 @@ namespace Flow.Launcher
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 15579a61d..23a316304 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 b333aba42..742d85fc1 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Main.cs
@@ -3,7 +3,6 @@ using System.Linq;
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 @@ namespace Flow.Launcher.Plugin.PluginsManager
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 9d2a8fe73..c742e457c 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 @@ namespace Flow.Launcher.Plugin.PluginsManager
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 @@ namespace Flow.Launcher.Plugin.PluginsManager
}
var updateSource = !updateFromLocalPath
- ? PluginsManifest.UserPlugins
+ ? Context.API.GetUserPlugins()
: new List { pluginFromLocalPath };
var resultsForUpdate = (
@@ -601,7 +600,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
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 @@ namespace Flow.Launcher.Plugin.PluginsManager
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 0845/1697] 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 17517832b..aa6c54a94 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -454,16 +454,11 @@ namespace Flow.Launcher.Core.Plugin
#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 @@ namespace Flow.Launcher.Core.Plugin
_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 @@ namespace Flow.Launcher.Core.Plugin
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 513c2da84..eeb3f5de3 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -352,15 +352,54 @@ namespace Flow.Launcher.Plugin
/// 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 a8ec46982..c40e40ebb 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -358,7 +358,18 @@ namespace Flow.Launcher
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 23a316304..84d8a2ff9 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 c742e457c..a16778ff4 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.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
+using Flow.Launcher.Plugin.SharedCommands;
namespace Flow.Launcher.Plugin.PluginsManager
{
@@ -49,7 +48,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
{
return new List()
{
- new Result()
+ new()
{
Title = Settings.InstallCommand,
IcoPath = icoPath,
@@ -61,7 +60,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
return false;
}
},
- new Result()
+ new()
{
Title = Settings.UninstallCommand,
IcoPath = icoPath,
@@ -73,7 +72,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
return false;
}
},
- new Result()
+ new()
{
Title = Settings.UpdateCommand,
IcoPath = icoPath,
@@ -248,7 +247,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
}
var updateSource = !updateFromLocalPath
- ? Context.API.GetUserPlugins()
+ ? Context.API.GetPluginManifest()
: new List { pluginFromLocalPath };
var resultsForUpdate = (
@@ -258,7 +257,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
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 @@ namespace Flow.Launcher.Plugin.PluginsManager
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 @@ namespace Flow.Launcher.Plugin.PluginsManager
}
else
{
- await PluginManager.UpdatePluginAsync(x.PluginExistingMetadata, x.PluginNewUserPlugin,
+ await Context.API.UpdatePluginAsync(x.PluginExistingMetadata, x.PluginNewUserPlugin,
downloadToFilePath);
if (Settings.AutoRestartAfterChanging)
@@ -431,7 +430,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
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 @@ namespace Flow.Launcher.Plugin.PluginsManager
return new List
{
- new Result
+ new()
{
Title = $"{plugin.Name} by {plugin.Author}",
SubTitle = plugin.Description,
@@ -610,8 +609,8 @@ namespace Flow.Launcher.Plugin.PluginsManager
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 @@ namespace Flow.Launcher.Plugin.PluginsManager
try
{
- PluginManager.InstallPlugin(plugin, downloadedFilePath);
+ Context.API.InstallPlugin(plugin, downloadedFilePath);
if (!plugin.IsFromLocalInstallPath)
File.Delete(downloadedFilePath);
@@ -737,7 +736,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
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 0846/1697] 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 5a2259ff1..8ff41a7ad 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 0847/1697] 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 87f51d5d7..d18060e3d 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 0848/1697] 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 5c9189ae1..3488b4b93 100644
--- a/Flow.Launcher.Plugin/UserPlugin.cs
+++ b/Flow.Launcher.Plugin/UserPlugin.cs
@@ -73,7 +73,7 @@ namespace Flow.Launcher.Plugin
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 0849/1697] 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 3488b4b93..74a16b83d 100644
--- a/Flow.Launcher.Plugin/UserPlugin.cs
+++ b/Flow.Launcher.Plugin/UserPlugin.cs
@@ -53,7 +53,7 @@ namespace Flow.Launcher.Plugin
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 0850/1697] 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 e5980b62f..4cf9ce7a7 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -81,11 +81,6 @@ namespace Flow.Launcher.Core.Resource
#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 @@ namespace Flow.Launcher.Core.Resource
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 @@ namespace Flow.Launcher.Core.Resource
private ResourceDictionary GetCurrentResourceDictionary()
{
- return GetResourceDictionary(GetCurrentTheme());
+ return GetResourceDictionary(_settings.Theme);
}
private ThemeData GetThemeDataFromPath(string path)
@@ -383,9 +378,15 @@ namespace Flow.Launcher.Core.Resource
#endregion
- #region Load & Change
+ #region Get & Change Theme
- public List LoadAvailableThemes()
+ public ThemeData GetCurrentTheme()
+ {
+ var themes = GetAvailableThemes();
+ return themes.FirstOrDefault(t => t.FileNameWithoutExtension == _settings.Theme) ?? themes.FirstOrDefault();
+ }
+
+ public List GetAvailableThemes()
{
List themes = new List();
foreach (var themeDirectory in _themeDirectories)
@@ -403,7 +404,7 @@ namespace Flow.Launcher.Core.Resource
public bool ChangeTheme(string theme = null)
{
if (string.IsNullOrEmpty(theme))
- theme = GetCurrentTheme();
+ theme = _settings.Theme;
string path = GetThemePath(theme);
try
@@ -591,7 +592,7 @@ namespace Flow.Launcher.Core.Resource
{
AutoDropShadow(useDropShadowEffect);
}
- SetBlurForWindow(GetCurrentTheme(), backdropType);
+ SetBlurForWindow(_settings.Theme, backdropType);
if (!BlurEnabled)
{
@@ -610,7 +611,7 @@ namespace Flow.Launcher.Core.Resource
// 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 @@ namespace Flow.Launcher.Core.Resource
}
#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 f178ebb90..bfcc2f9e0 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -344,5 +344,24 @@ namespace Flow.Launcher.Plugin
/// 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 000000000..d4a69ef09
--- /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 d88eeb7c9..96ccb55c4 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -37,6 +37,9 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
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 0851/1697] 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 6e2488fe1..58cf3a314 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 31faeba52..84bfa218e 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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 @@ namespace Flow.Launcher.Plugin.Sys
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 0852/1697] 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 d4a69ef09..6cbd0fe74 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 class ThemeData
///
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 0853/1697] 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 6cbd0fe74..90a45182c 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 0854/1697] 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 90a45182c..1888be65e 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 0855/1697] 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 84bfa218e..4b99efe3b 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
@@ -38,7 +38,6 @@ namespace Flow.Launcher.Plugin.Sys
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 0856/1697] 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 5cd14ba7e..69d31a98d 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 3f8272dda..e36c647a2 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 0857/1697] - 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 24ab3cf94..b869a82e1 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 69d31a98d..5d55e8e2f 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 23ec6d242..bfab94f20 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 0858/1697] 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 cb1d8dbc4..a524dd7cb 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 0859/1697] Add help window with content dialogue style
---
.../Resources/CustomControlTemplate.xaml | 54 ++++++++++---------
Flow.Launcher/Resources/Dark.xaml | 2 +-
.../SettingsPanePluginsViewModel.cs | 3 +-
.../Views/SettingsPanePlugins.xaml | 2 +-
.../Views/SettingsPanePlugins.xaml.cs | 49 ++++++++++++++++-
5 files changed, 79 insertions(+), 31 deletions(-)
diff --git a/Flow.Launcher/Resources/CustomControlTemplate.xaml b/Flow.Launcher/Resources/CustomControlTemplate.xaml
index aeb8f872f..31e9d1f13 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 754b15989..af1653c93 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 partial class SettingsPanePluginsViewModel : BaseModel
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 partial class SettingsPanePluginsViewModel : BaseModel
if (_isOnOffSelected != value)
{
_isOnOffSelected = value;
- OnPropertyChanged(nameof(IsOnOffSelected));
- UpdateDisplayMode();
+ OnPropertyChanged();
}
}
}
@@ -80,8 +62,7 @@ public partial class SettingsPanePluginsViewModel : BaseModel
if (_isPrioritySelected != value)
{
_isPrioritySelected = value;
- OnPropertyChanged(nameof(IsPrioritySelected));
- UpdateDisplayMode();
+ OnPropertyChanged();
}
}
}
@@ -95,38 +76,15 @@ public partial class SettingsPanePluginsViewModel : BaseModel
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 @@ public partial class SettingsPanePluginsViewModel : BaseModel
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 5498b293c..f9f708314 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 0879/1697] 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 da92a3583..7fb9b895a 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/PluginSettings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/PluginSettings.cs
@@ -120,10 +120,9 @@ namespace Flow.Launcher.Infrastructure.UserSettings
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 6cb20d12f..d89340e19 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -322,8 +322,10 @@ namespace Flow.Launcher.Infrastructure.UserSettings
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 1496765ce..da10bc6a5 100644
--- a/Flow.Launcher.Plugin/PluginMetadata.cs
+++ b/Flow.Launcher.Plugin/PluginMetadata.cs
@@ -99,10 +99,9 @@ namespace Flow.Launcher.Plugin
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 ae1daabe0..000000000
--- 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 78486dad4..5d9b16e0b 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 615904d66..5ba011fed 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 0fd98bfac..000000000
--- 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 ad9284074..000000000
--- 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 b379b875f..000000000
--- 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 649913872..000000000
--- 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 1c7ca58d0..000000000
--- 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 4a3c9f5a7..000000000
--- 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 cec8c318c..74e2d8340 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 partial class SettingsPaneGeneralViewModel : BaseModel
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 partial class SettingsPaneGeneralViewModel : BaseModel
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 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
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 e36c647a2..10e2b549a 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 2016d9c98..bf61b1902 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -95,7 +95,7 @@ namespace Flow.Launcher.ViewModel
}
}
- public SearchDelayTime? PluginSearchDelayTime
+ public int? PluginSearchDelayTime
{
get => PluginPair.Metadata.SearchDelayTime;
set
@@ -192,12 +192,5 @@ namespace Flow.Launcher.ViewModel
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 64681f803..c8b6310a7 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 0880/1697] 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 af1653c93..46e398eb5 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
@@ -141,7 +141,7 @@ public partial class SettingsPanePluginsViewModel : BaseModel
},
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 0881/1697] 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 33ed54bb4..000000000
--- 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 fbe2a941d..000000000
--- 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 5ba011fed..778f00160 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 @@ namespace Flow.Launcher.ViewModel
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 0882/1697] 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 778f00160..f57c0e2d9 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 22a69592b..2dff72ac5 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -93,13 +93,23 @@ namespace Flow.Launcher.ViewModel
}
}
- 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 0883/1697] 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 24ab3cf94..3de278eca 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 91f648586..431293a50 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 0884/1697] 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 f57c0e2d9..ece66034c 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 dfa03a204..ab9496266 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 partial class 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 0885/1697] - 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 d89340e19..e304a1b50 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -321,10 +321,6 @@ namespace Flow.Launcher.Infrastructure.UserSettings
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 5d9b16e0b..f01d0575a 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 ece66034c..9a4e3b7b0 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 b51e5fec0..157910b4a 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 74e2d8340..35dbab647 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -32,25 +32,7 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
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 partial class SettingsPaneGeneralViewModel : BaseModel
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 46e398eb5..4958bb7b7 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
@@ -122,7 +122,7 @@ public partial class SettingsPanePluginsViewModel : BaseModel
{
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 @@ public partial class SettingsPanePluginsViewModel : BaseModel
},
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 10e2b549a..657e97f30 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 0886/1697] 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 157910b4a..d78829471 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 0887/1697] Add function for switch and button
---
Flow.Launcher/Languages/en.xaml | 6 +-
.../SettingsPaneGeneralViewModel.cs | 122 ++++++++++++++----
.../Views/SettingsPaneGeneral.xaml | 62 ++++-----
3 files changed, 133 insertions(+), 57 deletions(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 3de278eca..c4c87dbc4 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 a1b38a53c..dcd17cf24 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -13,6 +13,8 @@ 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;
@@ -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 partial class SettingsPaneGeneralViewModel : BaseModel
_portable = portable;
UpdateEnumDropdownLocalizations();
IsLegacyKoreanIMEEnabled();
+ OpenImeSettingsCommand = new RelayCommand(OpenImeSettings);
}
public class SearchWindowScreenData : DropdownDataGeneric { }
@@ -190,8 +194,89 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
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.CreateSubKey(subKeyPath))
+ {
+ if (key != null)
+ {
+ int value = enable ? 1 : 0;
+ key.SetValue(valueName, value, RegistryValueKind.DWord);
+ return true;
+ }
+ else
+ {
+ 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";
@@ -202,25 +287,7 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
{
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}' 값이 존재하지 않습니다.");
- }
- }
- else
- {
- Debug.WriteLine($"[IME DEBUG] 레지스트리 키를 찾을 수 없습니다: {subKeyPath}");
+ return key.GetValue(valueName);
}
}
}
@@ -229,10 +296,21 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
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 431293a50..1d4dfd8ae 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 0888/1697] 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 4cf9ce7a7..f3eba7ba7 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -16,6 +16,7 @@ using Flow.Launcher.Infrastructure;
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 64bdcec34..1090a3a1e 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.Runtime.CompilerServices;
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 1888be65e..6a5e54f55 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 58cf3a314..f78704ef2 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
@@ -12,6 +12,7 @@ using Flow.Launcher.Helper;
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 4b99efe3b..feacc3f99 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 0889/1697] 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 6a5e54f55..322985f3a 100644
--- a/Flow.Launcher.Plugin/SharedModels/ThemeData.cs
+++ b/Flow.Launcher.Plugin/SharedModels/ThemeData.cs
@@ -41,12 +41,16 @@ public class ThemeData
///
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 0890/1697] 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 30004952e..111bc716c 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -228,7 +228,7 @@ namespace Flow.Launcher.Plugin
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 0891/1697] 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 322985f3a..093e1ee8e 100644
--- a/Flow.Launcher.Plugin/SharedModels/ThemeData.cs
+++ b/Flow.Launcher.Plugin/SharedModels/ThemeData.cs
@@ -43,6 +43,8 @@ public class ThemeData
{
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 0892/1697] 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 093e1ee8e..cb389c21f 100644
--- a/Flow.Launcher.Plugin/SharedModels/ThemeData.cs
+++ b/Flow.Launcher.Plugin/SharedModels/ThemeData.cs
@@ -51,8 +51,6 @@ public class ThemeData
///
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 0893/1697] 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 f3eba7ba7..d7c619330 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -384,7 +384,12 @@ namespace Flow.Launcher.Core.Resource
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 0894/1697] 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 d3c50b406..6d2ae70fc 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -27,6 +27,9 @@ namespace Flow.Launcher.Plugin.Program
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 @@ namespace Flow.Launcher.Plugin.Program
{
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 @@ namespace Flow.Launcher.Plugin.Program
.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 @@ namespace Flow.Launcher.Plugin.Program
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 @@ namespace Flow.Launcher.Plugin.Program
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 @@ namespace Flow.Launcher.Plugin.Program
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 @@ namespace Flow.Launcher.Plugin.Program
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 e4d7c323a..b89a2a6ba 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 @@ namespace Flow.Launcher.Plugin.Program.Views.Commands
.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 @@ namespace Flow.Launcher.Plugin.Program.Views.Commands
}
}
- 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 @@ namespace Flow.Launcher.Plugin.Program.Views.Commands
program.Enabled = status;
}
}
+ Main._uwpsLock.Release();
}
internal static void StoreDisabledInSettings()
@@ -72,12 +80,22 @@ namespace Flow.Launcher.Plugin.Program.Views.Commands
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 5ad7fcea3..c42bd4f30 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 @@ namespace Flow.Launcher.Plugin.Program.Views
EditProgramSource(selectedProgramSource);
}
- private void EditProgramSource(ProgramSource selectedProgramSource)
+ private async void EditProgramSource(ProgramSource selectedProgramSource)
{
if (selectedProgramSource == null)
{
@@ -202,13 +202,13 @@ namespace Flow.Launcher.Plugin.Program.Views
{
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 @@ namespace Flow.Launcher.Plugin.Program.Views
}
}
- 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 @@ namespace Flow.Launcher.Plugin.Program.Views
}
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 0895/1697] 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 d7c619330..59e76e2d2 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -433,7 +433,7 @@ namespace Flow.Launcher.Core.Resource
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 056c4a437..7701fcdd0 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -367,8 +367,10 @@ namespace Flow.Launcher.Plugin
/// 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 b19b21db1..8cce460d7 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -377,11 +377,8 @@ namespace Flow.Launcher
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 0896/1697] 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 feacc3f99..f8aeaeafd 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
@@ -76,8 +76,10 @@ namespace Flow.Launcher.Plugin.Sys
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 0897/1697] 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 6d2ae70fc..a5fbc6c70 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -367,7 +367,7 @@ namespace Flow.Launcher.Plugin.Program
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 @@ namespace Flow.Launcher.Plugin.Program
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 @@ namespace Flow.Launcher.Plugin.Program
});
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 @@ namespace Flow.Launcher.Plugin.Program
_ = 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 0898/1697] 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 f218c5d8d..b5de3b50f 100644
--- a/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs
@@ -42,8 +42,7 @@ namespace Flow.Launcher.Infrastructure.Storage
public async ValueTask TryLoadAsync(T defaultData)
{
- if (Data != null)
- return Data;
+ if (Data != null) return Data;
if (File.Exists(FilePath))
{
@@ -55,8 +54,7 @@ namespace Flow.Launcher.Infrastructure.Storage
}
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 b63e8c1ef..e8cbd70fb 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 cabd26962..0d23c0fc8 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 4dd0268d2..a523f90bb 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -229,9 +229,6 @@ namespace Flow.Launcher
}
}
- ///
- /// Save plugin settings.
- ///
public void SavePluginSettings()
{
foreach (var value in _pluginJsonStorages.Values)
@@ -378,9 +375,6 @@ namespace Flow.Launcher
}
}
- ///
- /// 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 a5fbc6c70..561044981 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -77,10 +77,6 @@ namespace Flow.Launcher.Plugin.Program
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 @@ namespace Flow.Launcher.Plugin.Program
.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 @@ namespace Flow.Launcher.Plugin.Program
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 @@ namespace Flow.Launcher.Plugin.Program
{
_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 @@ namespace Flow.Launcher.Plugin.Program
{
_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 @@ namespace Flow.Launcher.Plugin.Program
}
else
{
- // Release the lock if we cannot find the program
_uwpsLock.Release();
}
@@ -425,7 +419,6 @@ namespace Flow.Launcher.Plugin.Program
}
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 0899/1697] 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 fc34395e0..bcf1cdd5e 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 0900/1697] 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 561044981..c235fb587 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -186,6 +186,8 @@ namespace Flow.Launcher.Plugin.Program
_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 @@ namespace Flow.Launcher.Plugin.Program
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 <{_win32sCount}>");
+ Log.Info($"|Flow.Launcher.Plugin.Program.Main|Number of preload uwps <{_uwpsCount}>");
- 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();
+ 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 0901/1697] 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 c235fb587..11deb710d 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -283,32 +283,52 @@ namespace Flow.Launcher.Plugin.Program
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 0902/1697] 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 2f8672e13..85c48f8a4 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -366,7 +366,7 @@ namespace Flow.Launcher.Plugin
/// 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 0903/1697] 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 0d23c0fc8..38cbf8e08 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 0904/1697] 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 11deb710d..107673f89 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -413,10 +413,7 @@ namespace Flow.Launcher.Plugin.Program
_uwpsLock.Release();
// Reindex UWP programs
- _ = Task.Run(() =>
- {
- _ = IndexUwpProgramsAsync();
- });
+ _ = Task.Run(IndexUwpProgramsAsync);
return;
}
else
@@ -433,10 +430,8 @@ namespace Flow.Launcher.Plugin.Program
_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 0905/1697] 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 b5de3b50f..43bb8dade 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 85c48f8a4..a3020b607 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -380,7 +380,7 @@ namespace Flow.Launcher.Plugin
/// 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 0906/1697] 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 107673f89..745b042e6 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -190,8 +190,8 @@ namespace Flow.Launcher.Plugin.Program
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 @@ namespace Flow.Launcher.Plugin.Program
// 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 0907/1697] 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 745b042e6..a50868b69 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -258,9 +258,6 @@ namespace Flow.Launcher.Plugin.Program
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 0908/1697] 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 f01d0575a..7e5a554a9 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 0909/1697] 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 ab9496266..a27a00782 100644
--- a/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml.cs
+++ b/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml.cs
@@ -9,6 +9,7 @@ public partial class 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 0910/1697] 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 9a4e3b7b0..63d1af6b1 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 2dff72ac5..5f19459c9 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -3,9 +3,11 @@ using System.Threading.Tasks;
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 @@ namespace Flow.Launcher.ViewModel
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 0911/1697] 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 63d1af6b1..4a89d811f 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 0912/1697] 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 7e5a554a9..609859d0d 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 4a89d811f..231036244 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 5f19459c9..da0ed70fa 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -153,6 +153,7 @@ namespace Flow.Launcher.ViewModel
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 0913/1697] 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 dd6edaff9..784d323fe 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 @@ namespace Flow.Launcher.Infrastructure
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 0914/1697] 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 d78829471..ffa5eea41 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 e8629a981..498e96bff 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 aa6da9fb2..0f1e98a6b 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 0915/1697] 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 273676bfb..6d9e5f755 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -473,5 +473,31 @@ namespace Flow.Launcher.Plugin
///
///
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 b67ef6ab6..b7aaef143 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -31,6 +31,7 @@ using Flow.Launcher.Plugin.SharedCommands;
using Flow.Launcher.ViewModel;
using JetBrains.Annotations;
using Squirrel;
+using Stopwatch = Flow.Launcher.Infrastructure.Stopwatch;
namespace Flow.Launcher
{
@@ -431,6 +432,18 @@ namespace Flow.Launcher
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 0916/1697] 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 6d9e5f755..55f09dc3b 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -479,25 +479,25 @@ namespace Flow.Launcher.Plugin
/// 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 b7aaef143..95ef6c9f3 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -432,16 +432,16 @@ namespace Flow.Launcher
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 0917/1697] 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 41a33104b..1483c5865 100644
--- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
@@ -7,13 +7,20 @@ using System.Threading;
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 @@ namespace Flow.Launcher.Infrastructure.Image
_ = 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 @@ namespace Flow.Launcher.Infrastructure.Image
}
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 @@ namespace Flow.Launcher.Infrastructure.Image
}
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 0918/1697] 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 a57179da6..b5eafaae9 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 92721b70a..806e9f203 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 629173f74..6055a79e1 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 8a7e3498a..4fb441d8c 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 1ab69727b..23d58eca3 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 4cba4c8a7..8b3c42fa6 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 d0d1d010d..e46e0dc9d 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 c912052f1..38e943cda 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 e4d4d3e2c..fd34bf366 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 28c334667..e6f2223cd 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 d9da26bcb..3aee3f5e4 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 a37a204e1..b78bcb7d7 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 64adccd94..ce3406142 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 06204395c..12af37c3e 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 62293b1a1..d0040d799 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 bad37f688..9dc520cbd 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 a56a770da..c38855474 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 332528b2b..0f07387c6 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 b244c4660..1d1eb9120 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 5d550ebed..b9b5d351e 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 95a746a51..427511c66 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 17e421e16..6223efc00 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 d9966d757..3d302da5b 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 01b667e72..cecad8e0d 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 4cdd4c934..d8d3a586f 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 41a4abfcf..cc78c9a9a 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 df162af92..47ea31cce 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 4104bd757..04619239d 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 4dc11fcec..d621b63c4 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 c4cc85463..8563f49a0 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 8697818dc..766d170a4 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 2dd0745c3..9b4a20a69 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 27fda1db7..ab788075e 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 ec880406a..7064de1fe 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 018435eca..8567b5412 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 1ea52e741..1333fe573 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 c4cc85463..8563f49a0 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 a19c958b4..c3d1f6d08 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 f06121887..1210818bf 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 c4cc85463..cfcd71c37 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 a111f8776..650f14657 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 c4cc85463..8563f49a0 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 b5c75f2d9..944a883c9 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 26963bddb..0e2bef052 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 bfa4792e4..2b06d3bbe 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 c4cc85463..8563f49a0 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 c4cc85463..8563f49a0 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 e23f43875..02dab46ba 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 0bf065ee1..89fd67635 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 160ca5f96..15e717c79 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 c4cc85463..8563f49a0 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 662765760..14e228b2a 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 0e8b2f1d5..af272fb46 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 77a3fed47..dcfc82e0a 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 529be9f45..ccc50678e 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 1a42ce51b..de35c9592 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 172adfd2f..91230e7e3 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 cdd0e0348..794e949ad 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 99eec60fa..ac4040dca 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 2139738f7..5f3688ab8 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 727a9a6ad..5419bd8e2 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 acc3f3b59..86688a130 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 b464cab28..be31e4e52 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 cff426d4e..bc7dff59f 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 d9b568e14..f2049038f 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 a531189fe..072fd623d 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 e0e4d46a8..9d1d54076 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 bbb3bec88..c09a447d2 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 b356f6bc7..a19ab39d6 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 aa7217c01..9e0e39066 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 4547274f8..796cda69d 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 0f8894288..087ff9f05 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 d04a783d0..f5a2f1b30 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 93973913f..18f7f63f5 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 57c83e1a5..19d69511b 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 8d0bc43c0..dae12c501 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 e08f312b1..745129130 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 d43496466..573aefcbd 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 6e92178db..cefb5d1d1 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 849f27f05..ca98581c3 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 2a7d4aa32..b1113acb7 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 0c72b11bf..2a7dca596 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 517ac0918..3ce22bb78 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 e6e4a94d2..7f14b59c6 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 c6b1b145c..f04cfb48a 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 630287983..78ee7ca7d 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 26c1e8459..db2a4dfeb 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 85ce0e282..9ae628853 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 5ab5fffa3..3ac9f6a6c 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 4bba382a9..9f793c43f 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 a48d99487..a18710324 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 499351343..d693a3f28 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 d4135c795..6f0d7fcc9 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 16969dac7..1a2476a2c 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 c59182290..1fd9aca96 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 44b765c58..1afcdb360 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 5f1803655..06707b4af 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 1506b753b..aaad035a0 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 beb085d28..5536a7e68 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 e3105283f..731275c5e 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 d3df223cc..375a741d0 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 eb58a4ec0..727b2f4a9 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 dcc74d520..5f8d9a6df 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 55ac42dd3..faa8c2dcc 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 c7c1854b7..ab69a2a31 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 e7f8e1683..39062bbb8 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 f47b9ada3..5b4dea6a9 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 0919/1697] 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 a50868b69..f03040d68 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -6,7 +6,6 @@ using System.Linq;
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.Program.Views.Models;
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 @@ namespace Flow.Launcher.Plugin.Program
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 @@ namespace Flow.Launcher.Plugin.Program
}
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 @@ namespace Flow.Launcher.Plugin.Program
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 @@ namespace Flow.Launcher.Plugin.Program
_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 @@ namespace Flow.Launcher.Plugin.Program
}
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 @@ namespace Flow.Launcher.Plugin.Program
}
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 @@ namespace Flow.Launcher.Plugin.Program
{
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 0920/1697] 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 0ee268f5c..4c85fb061 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 @@ namespace Flow.Launcher.Core.Plugin
{
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 @@ namespace Flow.Launcher.Core.Plugin
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 495a4c1ab..1010d9f08 100644
--- a/Flow.Launcher.Core/Plugin/PluginsLoader.cs
+++ b/Flow.Launcher.Core/Plugin/PluginsLoader.cs
@@ -11,12 +11,17 @@ using Flow.Launcher.Infrastructure.Logger;
#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 @@ namespace Flow.Launcher.Core.Plugin
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 81938612c..90fefe0a6 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -21,7 +21,6 @@ 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
{
@@ -35,6 +34,8 @@ namespace Flow.Launcher
#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 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
_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 0921/1697] 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 d2b85e687..407300924 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
@@ -524,7 +524,7 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
}
}
- 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 0922/1697] 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 5dec8b953..3eb74dd74 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.IO;
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 class Main : ISettingProvider, IPlugin, IReloadable, IPluginI18n, IContex
_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 0923/1697] 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 282876472..27bcbd9a9 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 @@ public abstract class ChromiumBookmarkLoader : IBookmarkLoader
}
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 3f3b7cb58..f6de65e90 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 @@ namespace Flow.Launcher.Plugin.Explorer
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 9fd495f49..1a0d3bd15 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 @@ namespace Flow.Launcher.Plugin.Explorer.Search.DirectoryInfo
}
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 66230937c..2aeb421e0 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.Runtime.InteropServices;
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 @@ namespace Flow.Launcher.Plugin.Explorer.Search.WindowsIndex
}
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 a50868b69..acfa0655e 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -6,7 +6,6 @@ using System.Linq;
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 @@ namespace Flow.Launcher.Plugin.Program
}
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 @@ namespace Flow.Launcher.Plugin.Program
_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 @@ namespace Flow.Launcher.Plugin.Program
}
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 @@ namespace Flow.Launcher.Plugin.Program
}
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 53479b81f..97ff61304 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
@@ -8,7 +8,6 @@ using System.Threading.Tasks;
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 @@ namespace Flow.Launcher.Plugin.Shell
}
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 @@ namespace Flow.Launcher.Plugin.Shell
{
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 @@ namespace Flow.Launcher.Plugin.Shell
{
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 @@ namespace Flow.Launcher.Plugin.Shell
.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 @@ namespace Flow.Launcher.Plugin.Shell
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 @@ namespace Flow.Launcher.Plugin.Shell
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 @@ namespace Flow.Launcher.Plugin.Shell
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 @@ namespace Flow.Launcher.Plugin.Shell
{
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 @@ namespace Flow.Launcher.Plugin.Shell
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 @@ namespace Flow.Launcher.Plugin.Shell
// 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 @@ namespace Flow.Launcher.Plugin.Shell
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 @@ namespace Flow.Launcher.Plugin.Shell
{
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 @@ namespace Flow.Launcher.Plugin.Shell
},
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 @@ namespace Flow.Launcher.Plugin.Shell
},
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 94a9d0348..043eb7a19 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -6,7 +6,6 @@ using System.Linq;
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 @@ namespace Flow.Launcher.Plugin.Sys
{
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 @@ namespace Flow.Launcher.Plugin.Sys
{
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 0924/1697] 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 c2d0a46a0..73726ab37 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 0925/1697] 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 363ecb9d0..18b206022 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 95bb25837..321f17cc1 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 e3e2b705e..0596691cc 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 8f443214b..c7ea7cdd5 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 97ff61304..b149884d7 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
@@ -7,7 +7,6 @@ using System.Linq;
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 @@ namespace Flow.Launcher.Plugin.Shell
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 @@ namespace Flow.Launcher.Plugin.Shell
{
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 @@ namespace Flow.Launcher.Plugin.Shell
}
}
- 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 0926/1697] 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 273676bfb..ff0f1ba4a 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -372,6 +372,7 @@ namespace Flow.Launcher.Plugin
///
public bool SetCurrentTheme(ThemeData theme);
+ ///
/// Save all Flow's plugins caches
///
void SavePluginCaches();
@@ -404,6 +405,7 @@ namespace Flow.Launcher.Plugin
///
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 @@ namespace Flow.Launcher.Plugin
///
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 0927/1697] 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 b149884d7..0d395c053 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
@@ -13,7 +13,7 @@ using Keys = System.Windows.Forms.Keys;
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 @@ namespace Flow.Launcher.Plugin.Shell
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 0928/1697] Improve api documents
---
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 40 +++++++++++++++++--
1 file changed, 36 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index ff0f1ba4a..6f17f57f5 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -142,15 +142,47 @@ namespace Flow.Launcher.Plugin
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 0929/1697] 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 266c24170..dbc36ad42 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 0930/1697] 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 acfa0655e..99fa44257 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -275,7 +275,7 @@ namespace Flow.Launcher.Plugin.Program
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 bf100ed7e..cb33250e1 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.Threading.Tasks;
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 @@ namespace Flow.Launcher.Plugin.Program.Programs
}
}
- 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 @@ namespace Flow.Launcher.Plugin.Program.Programs
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 @@ namespace Flow.Launcher.Plugin.Program.Programs
{
var contextMenus = new List
{
- new Result
+ new()
{
Title = api.GetTranslation("flowlauncher_plugin_program_open_containing_folder"),
Action = _ =>
@@ -496,9 +495,9 @@ namespace Flow.Launcher.Plugin.Program.Programs
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 @@ namespace Flow.Launcher.Plugin.Program.Programs
{
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 06be2a628..a87b002d4 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.Security;
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 @@ namespace Flow.Launcher.Plugin.Program.Programs
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 @@ namespace Flow.Launcher.Plugin.Program.Programs
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 @@ namespace Flow.Launcher.Plugin.Program.Programs
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 @@ namespace Flow.Launcher.Plugin.Program.Programs
{
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 @@ namespace Flow.Launcher.Plugin.Program.Programs
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 @@ namespace Flow.Launcher.Plugin.Program.Programs
return Name;
}
- private static List Watchers = new List();
+ private static readonly List Watchers = new();
private static Win32 Win32Program(string path)
{
@@ -402,7 +401,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
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 @@ namespace Flow.Launcher.Plugin.Program.Programs
}
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 @@ namespace Flow.Launcher.Plugin.Program.Programs
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 @@ namespace Flow.Launcher.Plugin.Program.Programs
_ = 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 0931/1697] 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 21d964c11..1e662de9e 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 aea0d77a1..05e8d960f 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 @@ namespace Flow.Launcher.Plugin.PluginIndicator
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 0932/1697] 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 350c892cf..f9504e6d9 100644
--- a/Flow.Launcher.Infrastructure/UI/EnumBindingSource.cs
+++ b/Flow.Launcher.Infrastructure/UI/EnumBindingSource.cs
@@ -3,6 +3,7 @@ using System.Windows.Markup;
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 0933/1697] 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 81600e023..fdda33926 100644
--- a/Flow.Launcher.Core/Resource/LocalizationConverter.cs
+++ b/Flow.Launcher.Core/Resource/LocalizationConverter.cs
@@ -6,6 +6,7 @@ using System.Windows.Data;
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 0934/1697] 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 52a232334..3e1a19a76 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 @@ namespace Flow.Launcher.Core.Resource
{
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 ebab99e5b..eb0032758 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 84d8a2ff9..fd2c8e09f 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs
@@ -32,7 +32,7 @@ public partial class SettingsPanePluginStoreViewModel : BaseModel
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 4958bb7b7..b89e970e9 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
@@ -106,8 +106,8 @@ public partial class SettingsPanePluginsViewModel : BaseModel
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 1add84765..5c4accdc0 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 @@ namespace Flow.Launcher.Plugin.Explorer.Search
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 @@ namespace Flow.Launcher.Plugin.Explorer.Search
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 @@ namespace Flow.Launcher.Plugin.Explorer.Search
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 @@ namespace Flow.Launcher.Plugin.Explorer.Search
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 @@ namespace Flow.Launcher.Plugin.Explorer.Search
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 0935/1697] 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 99fa44257..54e59d1be 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -254,9 +254,8 @@ namespace Flow.Launcher.Plugin.Program
_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 0936/1697] 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 f6de65e90..f47907824 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs
@@ -393,7 +393,7 @@ namespace Flow.Launcher.Plugin.Explorer
{
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 @@ namespace Flow.Launcher.Plugin.Explorer
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 @@ namespace Flow.Launcher.Plugin.Explorer
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 0937/1697] 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 3eb74dd74..3bee49bf2 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs
@@ -32,7 +32,7 @@ public class Main : ISettingProvider, IPlugin, IReloadable, IPluginI18n, IContex
_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 0938/1697] 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 27bcbd9a9..7631aad91 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
@@ -37,7 +37,7 @@ public abstract class ChromiumBookmarkLoader : IBookmarkLoader
{
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 0939/1697] 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 ddbab4ef0..b8c12868b 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 @@ namespace Flow.Launcher.Infrastructure.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 0940/1697] 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 b91da7114..f02b2297f 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 41a33104b..6fd5c6277 100644
--- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
@@ -9,6 +9,8 @@ using System.Windows.Media;
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 @@ namespace Flow.Launcher.Infrastructure.Image
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 @@ namespace Flow.Launcher.Infrastructure.Image
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 @@ namespace Flow.Launcher.Infrastructure.Image
return img;
}
- private static BitmapImage LoadFullImage(string path)
+ private static ImageSource LoadFullImage(string path)
{
BitmapImage image = new BitmapImage();
image.BeginInit();
@@ -327,24 +344,24 @@ namespace Flow.Launcher.Infrastructure.Image
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 @@ namespace Flow.Launcher.Infrastructure.Image
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 6f17f57f5..f37496fd1 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -438,7 +438,9 @@ namespace Flow.Launcher.Plugin
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 d2f973329..113476703 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
@@ -159,16 +159,7 @@ public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader
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 @@ public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader
}
}
- 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("
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 @@ namespace Flow.Launcher.Core.Plugin
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 @@ namespace Flow.Launcher.Core.Plugin
}
};
- 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 @@ namespace Flow.Launcher.Core.Plugin
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 779dcf887..b134e2d50 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 abe563c14..d240ac9be 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
@@ -10,7 +10,6 @@ using Microsoft.VisualStudio.Threading;
using StreamJsonRpc;
using IAsyncDisposable = System.IAsyncDisposable;
-
namespace Flow.Launcher.Core.Plugin
{
internal abstract class JsonRPCPluginV2 : JsonRPCPluginBase, IAsyncDisposable, IAsyncReloadable, IResultUpdated
@@ -23,7 +22,6 @@ namespace Flow.Launcher.Core.Plugin
private JsonRpc RPC { get; set; }
-
protected override async Task ExecuteResultAsync(JsonRPCResult result)
{
var res = await RPC.InvokeAsync(result.JsonRPCAction.Method,
@@ -55,7 +53,6 @@ namespace Flow.Launcher.Core.Plugin
return results;
}
-
public override async Task InitAsync(PluginInitContext context)
{
await base.InitAsync(context);
@@ -88,7 +85,6 @@ namespace Flow.Launcher.Core.Plugin
protected abstract MessageHandlerType MessageHandler { get; }
-
private void SetupJsonRPC()
{
var formatter = new SystemTextJsonFormatter { JsonSerializerOptions = RequestSerializeOption };
@@ -118,9 +114,16 @@ namespace Flow.Launcher.Core.Plugin
{
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,9 +132,16 @@ namespace Flow.Launcher.Core.Plugin
{
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
{
RPC?.Dispose();
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 0953/1697] 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 d240ac9be..eda016d94 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
@@ -122,7 +122,7 @@ namespace Flow.Launcher.Core.Plugin
}
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 @@ namespace Flow.Launcher.Core.Plugin
}
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 0954/1697] 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 9f64e418c..b19bb6c79 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs
@@ -7,7 +7,6 @@ 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;
@@ -21,6 +20,8 @@ namespace Flow.Launcher.Core.Plugin
{
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 @@ namespace Flow.Launcher.Core.Plugin
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 @@ namespace Flow.Launcher.Core.Plugin
}
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 @@ namespace Flow.Launcher.Core.Plugin
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 @@ namespace Flow.Launcher.Core.Plugin
}
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 @@ namespace Flow.Launcher.Core.Plugin
{
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 b134e2d50..df0438409 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 @@ namespace Flow.Launcher.Core.Plugin
public abstract Task> QueryAsync(Query query, CancellationToken token);
-
private async Task InitSettingAsync()
{
JsonRpcConfigurationModel configuration = null;
@@ -119,7 +117,6 @@ namespace Flow.Launcher.Core.Plugin
await File.ReadAllTextAsync(SettingConfigurationPath));
}
-
Settings ??= new JsonRPCPluginSettings
{
Configuration = configuration, SettingPath = SettingPath, API = Context.API
@@ -130,7 +127,7 @@ namespace Flow.Launcher.Core.Plugin
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 eda016d94..6dccfa59b 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
@@ -16,6 +16,8 @@ namespace Flow.Launcher.Core.Plugin
{
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 @@ namespace Flow.Launcher.Core.Plugin
}
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 @@ namespace Flow.Launcher.Core.Plugin
}
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 0955/1697] 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 6dccfa59b..148fd969e 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
@@ -118,9 +118,11 @@ namespace Flow.Launcher.Core.Plugin
}
catch (RemoteMethodNotFoundException)
{
+ // Ignored
}
catch (ConnectionLostException)
{
+ // Ignored
}
catch (Exception e)
{
@@ -136,9 +138,11 @@ namespace Flow.Launcher.Core.Plugin
}
catch (RemoteMethodNotFoundException)
{
+ // Ignored
}
catch (ConnectionLostException)
{
+ // Ignored
}
catch (Exception e)
{
From 1f458d3b564a37944a7a10183fc9be5696cf2e95 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Apr 2025 20:06:17 +0800
Subject: [PATCH 0956/1697] Fix typos & Code quality
---
.../TranslationMapping.cs | 40 ++++++++++---------
1 file changed, 22 insertions(+), 18 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/TranslationMapping.cs b/Flow.Launcher.Infrastructure/TranslationMapping.cs
index c976fc522..b33a094db 100644
--- a/Flow.Launcher.Infrastructure/TranslationMapping.cs
+++ b/Flow.Launcher.Infrastructure/TranslationMapping.cs
@@ -8,8 +8,9 @@ namespace Flow.Launcher.Infrastructure
{
private bool constructed;
- private List originalIndexs = new List();
- private List translatedIndexs = new List();
+ private readonly List originalIndexes = new();
+ private readonly List translatedIndexes = new();
+
private int translatedLength = 0;
public void AddNewIndex(int originalIndex, int translatedIndex, int length)
@@ -17,46 +18,47 @@ namespace Flow.Launcher.Infrastructure
if (constructed)
throw new InvalidOperationException("Mapping shouldn't be changed after constructed");
- originalIndexs.Add(originalIndex);
- translatedIndexs.Add(translatedIndex);
- translatedIndexs.Add(translatedIndex + length);
+ originalIndexes.Add(originalIndex);
+ translatedIndexes.Add(translatedIndex);
+ translatedIndexes.Add(translatedIndex + length);
translatedLength += length - 1;
}
public int MapToOriginalIndex(int translatedIndex)
{
- if (translatedIndex > translatedIndexs.Last())
+ if (translatedIndex > translatedIndexes.Last())
return translatedIndex - translatedLength - 1;
int lowerBound = 0;
- int upperBound = originalIndexs.Count - 1;
+ int upperBound = originalIndexes.Count - 1;
int count = 0;
// Corner case handle
- if (translatedIndex < translatedIndexs[0])
+ if (translatedIndex < translatedIndexes[0])
return translatedIndex;
- if (translatedIndex > translatedIndexs.Last())
+
+ if (translatedIndex > translatedIndexes.Last())
{
int indexDef = 0;
- for (int k = 0; k < originalIndexs.Count; k++)
+ for (int k = 0; k < originalIndexes.Count; k++)
{
- indexDef += translatedIndexs[k * 2 + 1] - translatedIndexs[k * 2];
+ indexDef += translatedIndexes[k * 2 + 1] - translatedIndexes[k * 2];
}
return translatedIndex - indexDef - 1;
}
// Binary Search with Range
- for (int i = originalIndexs.Count / 2;; count++)
+ for (int i = originalIndexes.Count / 2;; count++)
{
- if (translatedIndex < translatedIndexs[i * 2])
+ if (translatedIndex < translatedIndexes[i * 2])
{
// move to lower middle
upperBound = i;
i = (i + lowerBound) / 2;
}
- else if (translatedIndex > translatedIndexs[i * 2 + 1] - 1)
+ else if (translatedIndex > translatedIndexes[i * 2 + 1] - 1)
{
lowerBound = i;
// move to upper middle
@@ -64,17 +66,19 @@ namespace Flow.Launcher.Infrastructure
i = (i + upperBound + 1) / 2;
}
else
- return originalIndexs[i];
+ {
+ return originalIndexes[i];
+ }
if (upperBound - lowerBound <= 1 &&
- translatedIndex > translatedIndexs[lowerBound * 2 + 1] &&
- translatedIndex < translatedIndexs[upperBound * 2])
+ translatedIndex > translatedIndexes[lowerBound * 2 + 1] &&
+ translatedIndex < translatedIndexes[upperBound * 2])
{
int indexDef = 0;
for (int j = 0; j < upperBound; j++)
{
- indexDef += translatedIndexs[j * 2 + 1] - translatedIndexs[j * 2];
+ indexDef += translatedIndexes[j * 2 + 1] - translatedIndexes[j * 2];
}
return translatedIndex - indexDef - 1;
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 0957/1697] 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 5d718466c..000000000
--- 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 d403d4847..ad24f2a76 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 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
{
if (oldActionKeywords.Count != newActionKeywords.Count)
{
- ReplaceActionKeyword(plugin.Metadata.ID, removedActionKeywords, addedActionKeywords);
+ ReplaceActionKeyword(_plugin.Metadata.ID, removedActionKeywords, addedActionKeywords);
return;
}
@@ -58,18 +55,16 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
}
// 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 5f0e1ea82..2c4dad4a9 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 class TextConverter : IValueConverter
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 53fa173a5..8b193fa1d 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 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
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 416f8e049..ecbdea606 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 @@ namespace Flow.Launcher
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 7b2fdfcf4..de5f5295b 100644
--- a/Flow.Launcher/Helper/HotKeyMapper.cs
+++ b/Flow.Launcher/Helper/HotKeyMapper.cs
@@ -3,7 +3,6 @@ using Flow.Launcher.Infrastructure.UserSettings;
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 @@ internal static class HotKeyMapper
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 class HotKeyMapper
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 class HotKeyMapper
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 678280bba..8762a934b 100644
--- a/Flow.Launcher/HotkeyControl.xaml.cs
+++ b/Flow.Launcher/HotkeyControl.xaml.cs
@@ -5,7 +5,6 @@ using System.Threading.Tasks;
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 @@ namespace Flow.Launcher
hotkeyControl.RefreshHotkeyInterface(hotkeyControl.Hotkey);
}
-
public static readonly DependencyProperty ChangeHotkeyProperty = DependencyProperty.Register(
nameof(ChangeHotkey),
typeof(ICommand),
@@ -79,7 +77,6 @@ namespace Flow.Launcher
set { SetValue(ChangeHotkeyProperty, value); }
}
-
public static readonly DependencyProperty TypeProperty = DependencyProperty.Register(
nameof(Type),
typeof(HotkeyType),
@@ -227,19 +224,18 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
}
}
-
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 2f8c5eb26..c7af8c5b8 100644
--- a/Flow.Launcher/HotkeyControlDialog.xaml.cs
+++ b/Flow.Launcher/HotkeyControlDialog.xaml.cs
@@ -5,7 +5,6 @@ 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;
@@ -34,7 +33,7 @@ public partial class HotkeyControlDialog : ContentDialog
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 partial class HotkeyControlDialog : ContentDialog
{
WindowTitle = windowTitle switch
{
- "" or null => InternationalizationManager.Instance.GetTranslation("hotkeyRegTitle"),
+ "" or null => App.API.GetTranslation("hotkeyRegTitle"),
_ => windowTitle
};
DefaultHotkey = defaultHotkey;
@@ -141,14 +140,14 @@ public partial class HotkeyControlDialog : ContentDialog
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 @@ public partial class HotkeyControlDialog : ContentDialog
else
{
tbMsg.Text = string.Format(
- InternationalizationManager.Instance.GetTranslation("hotkeyUnavailableUneditable"),
+ App.API.GetTranslation("hotkeyUnavailableUneditable"),
description
);
SaveBtn.IsEnabled = false;
@@ -176,7 +175,7 @@ public partial class HotkeyControlDialog : ContentDialog
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 880bfd9bc..64f52edff 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs
@@ -17,7 +17,9 @@ namespace Flow.Launcher.Resources.Pages
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 @@ namespace Flow.Launcher.Resources.Pages
}
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 35dbab647..57eb796d3 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 partial class SettingsPaneGeneralViewModel : BaseModel
public class SearchWindowAlignData : DropdownDataGeneric { }
public class SearchPrecisionData : DropdownDataGeneric { }
public class LastQueryModeData : DropdownDataGeneric { }
-
public bool StartFlowLauncherOnSystemStartup
{
@@ -61,7 +60,7 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
}
catch (Exception e)
{
- Notification.Show(InternationalizationManager.Instance.GetTranslation("setAutoStartFailed"),
+ Notification.Show(App.API.GetTranslation("setAutoStartFailed"),
e.Message);
}
}
@@ -89,7 +88,7 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
}
catch (Exception e)
{
- Notification.Show(InternationalizationManager.Instance.GetTranslation("setAutoStartFailed"),
+ Notification.Show(App.API.GetTranslation("setAutoStartFailed"),
e.Message);
}
}
@@ -121,7 +120,7 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
}
// 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 partial class SettingsPaneGeneralViewModel : BaseModel
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 partial class SettingsPaneGeneralViewModel : BaseModel
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 partial class SettingsPaneGeneralViewModel : BaseModel
private void SelectPython()
{
var selectedFile = GetFileFromDialog(
- InternationalizationManager.Instance.GetTranslation("selectPythonExecutable"),
+ App.API.GetTranslation("selectPythonExecutable"),
"Python|pythonw.exe"
);
@@ -249,7 +248,7 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
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 b13aaefe3..7a7c19dd3 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 @@ public partial class SettingsPaneHotkeyViewModel : BaseModel
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 @@ public partial class SettingsPaneHotkeyViewModel : BaseModel
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 @@ public partial class SettingsPaneHotkeyViewModel : BaseModel
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 @@ public partial class SettingsPaneHotkeyViewModel : BaseModel
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 e2f9e516c..38a6ef31e 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 partial class SettingsPaneProxyViewModel : BaseModel
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 dd7fd13a9..569d489d2 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 @@ public partial class SettingsPaneGeneral
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 0958/1697] 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 90fefe0a6..89faa105e 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -343,7 +343,7 @@ namespace Flow.Launcher
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 de5f5295b..b7b39ff31 100644
--- a/Flow.Launcher/Helper/HotKeyMapper.cs
+++ b/Flow.Launcher/Helper/HotKeyMapper.cs
@@ -136,7 +136,7 @@ internal static class HotKeyMapper
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 57eb796d3..069a7cb24 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -60,8 +60,7 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
}
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 partial class SettingsPaneGeneralViewModel : BaseModel
}
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 66481cad6..4a6c1d639 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -16,7 +16,6 @@ using CommunityToolkit.Mvvm.Input;
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 @@ namespace Flow.Launcher.ViewModel
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 0959/1697] 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 20b884b3d..83d4fd9e0 100644
--- a/Flow.Launcher.Core/Updater.cs
+++ b/Flow.Launcher.Core/Updater.cs
@@ -9,8 +9,6 @@ using System.Text.Json.Serialization;
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 @@ namespace Flow.Launcher.Core
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 @@ namespace Flow.Launcher.Core
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 0960/1697] 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 4c85fb061..29d91dc8d 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -205,7 +205,7 @@ namespace Flow.Launcher.Core.Plugin
}
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 0961/1697] 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 b7b39ff31..5e3b30281 100644
--- a/Flow.Launcher/Helper/HotKeyMapper.cs
+++ b/Flow.Launcher/Helper/HotKeyMapper.cs
@@ -137,7 +137,7 @@ internal static class HotKeyMapper
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 0962/1697] 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 5e3b30281..0771a6074 100644
--- a/Flow.Launcher/Helper/HotKeyMapper.cs
+++ b/Flow.Launcher/Helper/HotKeyMapper.cs
@@ -57,7 +57,7 @@ internal static class HotKeyMapper
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 class HotKeyMapper
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 0963/1697] 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 dc0799f90..1b0400d7b 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 ca8d2fd6c..6b0f9d440 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 0964/1697] 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 1b0400d7b..9315f05c9 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 0965/1697] 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 1713b3459..f82a32a8b 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 f50bc349e..8b82dc3b6 100644
--- a/Flow.Launcher/Resources/Controls/InfoBar.xaml.cs
+++ b/Flow.Launcher/Resources/Controls/InfoBar.xaml.cs
@@ -19,9 +19,7 @@ namespace Flow.Launcher.Resources.Controls
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 9590f7283..b98d76000 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -188,15 +188,21 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
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 6b0f9d440..16db1c676 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 0966/1697] - Fix String and adjust messages - Adjust Margin -
Cleanup comment
---
Flow.Launcher/Languages/en.xaml | 11 +-
.../SettingsPaneGeneralViewModel.cs | 175 +++++++++---------
.../Views/SettingsPaneGeneral.xaml | 6 +-
3 files changed, 96 insertions(+), 96 deletions(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 9315f05c9..bf430b6f5 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 b98d76000..701de4361 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -189,128 +189,129 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
}
}
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));
+ }
+ else
+ {
+ Debug.WriteLine("[DEBUG] Failed to set LegacyKoreanIMEEnabled");
}
}
+}
- public bool KoreanIMERegistryKeyExists => IsKoreanIMEExist();
+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()
+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 SetLegacyKoreanIMEEnabled(bool enable)
+bool IsKoreanIMEExist()
+{
+ return GetLegacyKoreanIMERegistryValue() != null;
+}
+
+bool IsLegacyKoreanIMEEnabled()
+{
+ object value = GetLegacyKoreanIMERegistryValue();
+
+ 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;
+ }
- try
+ 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))
{
- 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;
+ }
+ 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()
+{
+ 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;
}
-
- private void OpenImeSettings()
+ catch (Exception ex)
{
- try
- {
- Process.Start(new ProcessStartInfo("ms-settings:regionlanguage") { UseShellExecute = true });
- }
- catch (Exception e)
- {
- Debug.WriteLine($"Error opening IME settings: {e.Message}");
- }
+ Debug.WriteLine($"[IME DEBUG] Exception occurred: {ex.Message}");
}
+ 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 16db1c676..5304824fe 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 0967/1697] 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 8b82dc3b6..d447192cf 100644
--- a/Flow.Launcher/Resources/Controls/InfoBar.xaml.cs
+++ b/Flow.Launcher/Resources/Controls/InfoBar.xaml.cs
@@ -19,7 +19,6 @@ namespace Flow.Launcher.Resources.Controls
UpdateMessageVisibility();
UpdateOrientation();
UpdateIconAlignmentAndMargin();
- //this.DataContext = this;
}
public static readonly DependencyProperty TypeProperty =
@@ -48,7 +47,7 @@ namespace Flow.Launcher.Resources.Controls
set
{
SetValue(MessageProperty, value);
- UpdateMessageVisibility(); // Message 속성 변경 시 Visibility 업데이트
+ UpdateMessageVisibility(); // Visibility update when change Message
}
}
@@ -74,7 +73,7 @@ namespace Flow.Launcher.Resources.Controls
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 0968/1697] - Add Comment - Applied changes from CodeRabbit
---
.../Resources/Controls/InfoBar.xaml.cs | 2 +
.../SettingsPaneGeneralViewModel.cs | 187 +++++++++---------
2 files changed, 99 insertions(+), 90 deletions(-)
diff --git a/Flow.Launcher/Resources/Controls/InfoBar.xaml.cs b/Flow.Launcher/Resources/Controls/InfoBar.xaml.cs
index d447192cf..f4e26ea7c 100644
--- a/Flow.Launcher/Resources/Controls/InfoBar.xaml.cs
+++ b/Flow.Launcher/Resources/Controls/InfoBar.xaml.cs
@@ -19,6 +19,8 @@ namespace Flow.Launcher.Resources.Controls
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 701de4361..432ac998c 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -34,6 +34,7 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
_portable = portable;
_translater = translater;
UpdateEnumDropdownLocalizations();
+ // Initialize the Korean IME status by checking registry
IsLegacyKoreanIMEEnabled();
OpenImeSettingsCommand = new RelayCommand(OpenImeSettings);
}
@@ -188,129 +189,135 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
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));
- }
- else
- {
- Debug.WriteLine("[DEBUG] Failed to set LegacyKoreanIMEEnabled");
+ Debug.WriteLine($"[DEBUG] LegacyKoreanIMEEnabled changed: {value}");
+ if (SetLegacyKoreanIMEEnabled(value))
+ {
+ OnPropertyChanged(nameof(LegacyKoreanIMEEnabled));
+ OnPropertyChanged(nameof(KoreanIMERegistryValueIsZero));
+ }
+ else
+ {
+ Debug.WriteLine("[DEBUG] Failed to set LegacyKoreanIMEEnabled");
+ }
}
}
-}
-public bool KoreanIMERegistryKeyExists => IsKoreanIMEExist();
+ public bool KoreanIMERegistryKeyExists => IsKoreanIMEExist();
-public bool KoreanIMERegistryValueIsZero
-{
- get
+ 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 == 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)
+ bool SetLegacyKoreanIMEEnabled(bool enable)
{
- return intValue == 1;
- }
- else if (value != null && int.TryParse(value.ToString(), out int parsedValue))
- {
- 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;
-}
-
-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))
+ catch (Exception ex)
{
- if (key != null)
+ 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))
{
- return key.GetValue(valueName);
+ if (key != null)
+ {
+ return key.GetValue(valueName);
+ }
}
}
- }
- catch (Exception ex)
- {
- Debug.WriteLine($"[IME DEBUG] Exception occurred: {ex.Message}");
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"[IME DEBUG] Exception occurred: {ex.Message}");
+ }
+
+ return null;
}
- return null;
-}
-
-private void OpenImeSettings()
-{
- try
+ private void OpenImeSettings()
{
- Process.Start(new ProcessStartInfo("ms-settings:regionlanguage") { UseShellExecute = true });
+ try
+ {
+ Process.Start(new ProcessStartInfo("ms-settings:regionlanguage") { UseShellExecute = true });
+ }
+ catch (Exception e)
+ {
+ Debug.WriteLine($"Error opening IME settings: {e.Message}");
+ }
}
- 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 0969/1697] 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 f82a32a8b..3c6780690 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 0970/1697] 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 3c6780690..2ddcbdd0c 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 77470dbc2..ebf763e22 100644
--- a/Flow.Launcher/Resources/Controls/InfoBar.xaml.cs
+++ b/Flow.Launcher/Resources/Controls/InfoBar.xaml.cs
@@ -175,6 +175,11 @@ namespace Flow.Launcher.Resources.Controls
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 0971/1697] 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 3a20f81d5..33a7428db 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -206,7 +206,8 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
}
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 4b7db3cbd62233323bccfdd2188f28e8b6434a43 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 10 Apr 2025 09:36:47 +0800
Subject: [PATCH 0972/1697] Make function static
---
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 7045517f5..2882cb8f0 100644
--- a/Flow.Launcher.Infrastructure/StringMatcher.cs
+++ b/Flow.Launcher.Infrastructure/StringMatcher.cs
@@ -228,7 +228,7 @@ namespace Flow.Launcher.Infrastructure
return new MatchResult(false, UserSettingSearchPrecision);
}
- private bool IsAcronym(string stringToCompare, int compareStringIndex)
+ private static bool IsAcronym(string stringToCompare, int compareStringIndex)
{
if (IsAcronymChar(stringToCompare, compareStringIndex) || IsAcronymNumber(stringToCompare, compareStringIndex))
return true;
@@ -237,7 +237,7 @@ namespace Flow.Launcher.Infrastructure
}
// When counting acronyms, treat a set of numbers as one acronym ie. Visual 2019 as 2 acronyms instead of 5
- private bool IsAcronymCount(string stringToCompare, int compareStringIndex)
+ private static bool IsAcronymCount(string stringToCompare, int compareStringIndex)
{
if (IsAcronymChar(stringToCompare, compareStringIndex))
return true;
From f5fd6b569ca8466fe4922aa1bd975622217c81ee Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 10 Apr 2025 09:56:27 +0800
Subject: [PATCH 0973/1697] Use ReadOnlySpan instead
---
.../PinyinAlphabet.cs | 43 ++++++++++++-------
1 file changed, 28 insertions(+), 15 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
index 7bcc70251..1637a285c 100644
--- a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
+++ b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
@@ -1,4 +1,5 @@
-using System.Collections.Concurrent;
+using System;
+using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
@@ -148,9 +149,11 @@ namespace Flow.Launcher.Infrastructure
private static string ToDoublePin(string fullPinyin)
{
// Assuming s is valid
+ var fullPinyinSpan = fullPinyin.AsSpan();
var doublePin = new StringBuilder();
- if (fullPinyin.Length <= 3 && (fullPinyin[0] == 'a' || fullPinyin[0] == 'e' || fullPinyin[0] == 'o'))
+ // Handle special cases (a, o, e)
+ if (fullPinyin.Length <= 3 && (fullPinyinSpan[0] == 'a' || fullPinyinSpan[0] == 'e' || fullPinyinSpan[0] == 'o'))
{
if (special.TryGetValue(fullPinyin, out var value))
{
@@ -158,31 +161,41 @@ namespace Flow.Launcher.Infrastructure
}
}
- // zh, ch, sh
- if (fullPinyin.Length >= 2 && first.ContainsKey(fullPinyin[..2]))
+ // Check for initials that are two characters long (zh, ch, sh)
+ if (fullPinyin.Length >= 2)
{
- doublePin.Append(first[fullPinyin[..2]]);
+ var firstTwo = fullPinyinSpan[..2];
+ var firstTwoString = firstTwo.ToString();
+ if (first.ContainsKey(firstTwoString))
+ {
+ doublePin.Append(firstTwoString);
- if (second.TryGetValue(fullPinyin[2..], out var tmp))
- {
- doublePin.Append(tmp);
- }
- else
- {
- doublePin.Append(fullPinyin[2..]);
+ var lastTwo = fullPinyinSpan[2..];
+ var lastTwoString = lastTwo.ToString();
+ if (second.TryGetValue(lastTwoString, out var tmp))
+ {
+ doublePin.Append(tmp);
+ }
+ else
+ {
+ doublePin.Append(lastTwo);
+ }
}
}
+ // Handle single-character initials
else
{
- doublePin.Append(fullPinyin[0]);
+ doublePin.Append(fullPinyinSpan[0]);
- if (second.TryGetValue(fullPinyin[1..], out var tmp))
+ var lastOne = fullPinyinSpan[1..];
+ var lastOneString = lastOne.ToString();
+ if (second.TryGetValue(lastOneString, out var tmp))
{
doublePin.Append(tmp);
}
else
{
- doublePin.Append(fullPinyin[1..]);
+ doublePin.Append(lastOne);
}
}
From 22c0f59f202e993878ab2a0f884bb78b9a5ee75d Mon Sep 17 00:00:00 2001
From: DB p
Date: Thu, 10 Apr 2025 22:06:44 +0900
Subject: [PATCH 0974/1697] 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 4c3bd1d12..59a16e10c 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 0975/1697] 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 ffa5eea41..c18d5fa60 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 0976/1697] 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 609859d0d..a7fbca90a 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 231036244..619da22dc 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 c18d5fa60..ae3cc8018 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 0977/1697] 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 a7fbca90a..e53b75ae8 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 0978/1697] 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 ae3cc8018..de84e40d9 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 0979/1697] 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 de84e40d9..5a6b9a248 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 0980/1697] 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 5a6b9a248..1ff6ca49c 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 0981/1697] 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 ed94771f0..0d6f2e469 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 @@ public class QuerySuggestionBoxConverter : IMultiValueConverter
// 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 0982/1697] 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 59a16e10c..b57cb0d40 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 0983/1697] 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 f9c548de8..815f31280 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 @@ namespace Flow.Launcher.Infrastructure
}
#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 33a7428db..7eba1602f 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 partial class SettingsPaneGeneralViewModel : BaseModel
_portable = portable;
_translater = translater;
UpdateEnumDropdownLocalizations();
- OpenImeSettingsCommand = new RelayCommand(OpenImeSettings);
}
public class SearchWindowScreenData : DropdownDataGeneric { }
@@ -187,21 +180,22 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
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 partial class SettingsPaneGeneralViewModel : BaseModel
}
}
- 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 partial class SettingsPaneGeneralViewModel : BaseModel
}
}
- 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 0984/1697] 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 7eba1602f..2697a508e 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -10,7 +10,6 @@ using Flow.Launcher.Infrastructure;
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 0985/1697] 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 bf430b6f5..0df77b127 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 0986/1697] 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 0df77b127..f1c0a67cb 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 0987/1697] 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 815f31280..2df632545 100644
--- a/Flow.Launcher.Infrastructure/Win32Helper.cs
+++ b/Flow.Launcher.Infrastructure/Win32Helper.cs
@@ -21,6 +21,10 @@ namespace Flow.Launcher.Infrastructure
{
#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 2697a508e..13ae65894 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 partial class SettingsPaneGeneralViewModel : BaseModel
}
}
- 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 0988/1697] 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 d42505348..37a7ccb8d 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 73c35b1c8..b928a9815 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 @@ namespace Flow.Launcher.Plugin.Explorer.Views
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 3df50b3ed..746c9cf84 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 58577dbc1..0a1bdf6a2 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 @@ namespace Flow.Launcher.Plugin.WebSearch
}
}
}
+
+ //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 0989/1697] 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 2df632545..54604a271 100644
--- a/Flow.Launcher.Infrastructure/Win32Helper.cs
+++ b/Flow.Launcher.Infrastructure/Win32Helper.cs
@@ -21,10 +21,6 @@ namespace Flow.Launcher.Infrastructure
{
#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 @@ namespace Flow.Launcher.Infrastructure
#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 13ae65894..021c9d7fe 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -210,9 +210,9 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
{
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 partial class SettingsPaneGeneralViewModel : BaseModel
{
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 0990/1697] 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 5304824fe..4782d356e 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 0991/1697] 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 1bdb9d36a..6ca7be84d 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 0992/1697] 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 61566b415..02fb379fa 100644
--- a/Flow.Launcher/ViewModel/ResultsViewModel.cs
+++ b/Flow.Launcher/ViewModel/ResultsViewModel.cs
@@ -19,7 +19,7 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
#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 @@ namespace Flow.Launcher.ViewModel
}
}
-
#endregion
#region Public Methods
@@ -190,10 +189,10 @@ namespace Flow.Launcher.ViewModel
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 0993/1697] 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 e304a1b50..b48f047c5 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -101,6 +101,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
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 b57cb0d40..03bff03eb 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 0975398dc..41e5dd12e 100644
--- a/Flow.Launcher/ViewModel/ResultViewModel.cs
+++ b/Flow.Launcher/ViewModel/ResultViewModel.cs
@@ -123,6 +123,11 @@ namespace Flow.Launcher.ViewModel
}
}
+ 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 0994/1697] 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 910485438..2e4befdc2 100644
--- a/Flow.Launcher.Plugin/Result.cs
+++ b/Flow.Launcher.Plugin/Result.cs
@@ -60,7 +60,7 @@ namespace Flow.Launcher.Plugin
/// 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 @@ namespace Flow.Launcher.Plugin
///
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 @@ namespace Flow.Launcher.Plugin
///
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 0995/1697] 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 2e4befdc2..7e520175e 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 @@ namespace Flow.Launcher.Plugin
}
}
+ ///
+ /// 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 @@ namespace Flow.Launcher.Plugin
///
/// 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 @@ namespace Flow.Launcher.Plugin
}
}
- ///
- 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 @@ namespace Flow.Launcher.Plugin
///
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 @@ namespace Flow.Launcher.Plugin
///
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 @@ namespace Flow.Launcher.Plugin
///
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 4a6c1d639..38efca72b 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1268,8 +1268,7 @@ namespace Flow.Launcher.ViewModel
// 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 @@ namespace Flow.Launcher.ViewModel
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 0996/1697] 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 b48f047c5..d97a9ed1a 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -101,7 +101,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
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 609859d0d..66721d828 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 49306cd2d..574002a05 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 0997/1697] 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 7e520175e..70d11dadd 100644
--- a/Flow.Launcher.Plugin/Result.cs
+++ b/Flow.Launcher.Plugin/Result.cs
@@ -23,7 +23,7 @@ namespace Flow.Launcher.Plugin
private string _copyText = string.Empty;
- private string _badgePath;
+ private string _badgeIcoPath;
///
/// The title of the result. This is always required.
@@ -92,9 +92,9 @@ namespace Flow.Launcher.Plugin
///
/// 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 @@ namespace Flow.Launcher.Plugin
&& !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 @@ namespace Flow.Launcher.Plugin
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 38efca72b..0abd14ec5 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1286,9 +1286,9 @@ namespace Flow.Launcher.ViewModel
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 0998/1697] 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 70d11dadd..ac00d5af5 100644
--- a/Flow.Launcher.Plugin/Result.cs
+++ b/Flow.Launcher.Plugin/Result.cs
@@ -188,8 +188,9 @@ namespace Flow.Launcher.Plugin
// 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 0999/1697] 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 0abd14ec5..c1a237c6a 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1284,7 +1284,7 @@ namespace Flow.Launcher.ViewModel
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 1000/1697] 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 c1a237c6a..2155f7bf8 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -245,6 +245,14 @@ namespace Flow.Launcher.ViewModel
// 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 1001/1697] 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 03bff03eb..63c461c43 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 61e228de1..4137d5f58 100644
--- a/Flow.Launcher/ViewModel/ResultViewModel.cs
+++ b/Flow.Launcher/ViewModel/ResultViewModel.cs
@@ -125,13 +125,21 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
: 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 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
{
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 @@ namespace Flow.Launcher.ViewModel
}
}
+ 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 1002/1697] 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 d97a9ed1a..7c2457a72 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -102,6 +102,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
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 66721d828..87db45fbe 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 574002a05..57c9a5b70 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 1003/1697] 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 2155f7bf8..f6b9aa67c 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1208,11 +1208,11 @@ namespace Flow.Launcher.ViewModel
_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 27b385805..68c794aec 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 @@ namespace Flow.Launcher.ViewModel
}
}
- 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 1004/1697] 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 87db45fbe..024258f1b 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 1005/1697] 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 43bb8dade..414743d22 100644
--- a/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs
@@ -82,8 +82,8 @@ namespace Flow.Launcher.Infrastructure.Storage
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 @@ namespace Flow.Launcher.Infrastructure.Storage
// 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 cdf3ae909..f283be59e 100644
--- a/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
@@ -183,7 +183,10 @@ namespace Flow.Launcher.Infrastructure.Storage
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 @@ namespace Flow.Launcher.Infrastructure.Storage
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 1006/1697] 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 414743d22..b85111756 100644
--- a/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs
@@ -82,7 +82,9 @@ namespace Flow.Launcher.Infrastructure.Storage
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 @@ namespace Flow.Launcher.Infrastructure.Storage
// 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 1007/1697] 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 b85111756..64f809181 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 @@ namespace Flow.Launcher.Infrastructure.Storage
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 1008/1697] 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 29d91dc8d..94519bf6f 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -64,7 +64,14 @@ namespace Flow.Launcher.Core.Plugin
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 1009/1697] 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 94519bf6f..1d13dcfd3 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -37,7 +37,7 @@ namespace Flow.Launcher.Core.Plugin
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 @@ namespace Flow.Launcher.Core.Plugin
{
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 @@ namespace Flow.Launcher.Core.Plugin
{
// 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 ffa17ab4d..df841dbbe 100644
--- a/Flow.Launcher.Core/Resource/Internationalization.cs
+++ b/Flow.Launcher.Core/Resource/Internationalization.cs
@@ -22,8 +22,8 @@ namespace Flow.Launcher.Core.Resource
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 @@ namespace Flow.Launcher.Core.Resource
_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 @@ namespace Flow.Launcher.Core.Resource
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 @@ namespace Flow.Launcher.Core.Resource
{
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 @@ namespace Flow.Launcher.Core.Resource
}
}
- 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 @@ namespace Flow.Launcher.Core.Resource
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 95ef6c9f3..5438eac7d 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 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
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 1010/1697] Throw plugin exception for plugin dispose interface
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 21 ++++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 1d13dcfd3..f8a094575 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -88,14 +88,21 @@ namespace Flow.Launcher.Core.Plugin
private static async Task DisposePluginAsync(PluginPair pluginPair)
{
- switch (pluginPair.Plugin)
+ try
{
- case IDisposable disposable:
- disposable.Dispose();
- break;
- case IAsyncDisposable asyncDisposable:
- await asyncDisposable.DisposeAsync();
- break;
+ 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 1011/1697] 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 30afe67a1..bf7a45b1d 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -291,15 +291,15 @@ namespace Flow.Launcher
{
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 1012/1697] 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 64f809181..8ff10816c 100644
--- a/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs
@@ -45,10 +45,10 @@ namespace Flow.Launcher.Infrastructure.Storage
[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 8b4062b6b..ca78b2f20 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 1013/1697] 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 1de5841a5..6c506cfc0 100644
--- a/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs
+++ b/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs
@@ -264,12 +264,12 @@ namespace Flow.Launcher.Plugin.SharedCommands
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 @@ namespace Flow.Launcher.Plugin.SharedCommands
// 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 1014/1697] - 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 63c461c43..8231027f4 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 1015/1697] 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 e304a1b50..e1c6fbd1f 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -82,7 +82,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
/* 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 @@ namespace Flow.Launcher.Infrastructure.UserSettings
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 1016/1697] 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 f8a094575..52d6fd736 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -61,16 +61,16 @@ namespace Flow.Launcher.Core.Plugin
///
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 @@ namespace Flow.Launcher.Core.Plugin
}
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 1017/1697] 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 89faa105e..a9cd1a8b9 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -153,6 +153,7 @@ namespace Flow.Launcher
RegisterAppDomainExceptions();
RegisterDispatcherUnhandledException();
+ RegisterTaskSchedulerUnhandledException();
var imageLoadertask = ImageLoader.InitializeAsync();
@@ -284,6 +285,15 @@ namespace Flow.Launcher
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 5b79c520d..1787b1d91 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 class ErrorReporting
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 1018/1697] 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 f78704ef2..aa8ab7c4c 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
@@ -494,7 +494,7 @@ public partial class SettingsPaneThemeViewModel : BaseModel
{
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 1019/1697] 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 aaa23c8e2..f6a5444b3 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 24c7bd65b..9fb43b645 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 1045/1697] 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 e9713564e..27891a2d4 100644
--- a/Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs
@@ -19,7 +19,7 @@ namespace Flow.Launcher.Core.ExternalPlugins
private List plugins = new();
- private static JsonSerializerOptions PluginStoreItemSerializationOption = new JsonSerializerOptions()
+ private static readonly JsonSerializerOptions PluginStoreItemSerializationOption = new()
{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault
};
@@ -45,18 +45,18 @@ namespace Flow.Launcher.Core.ExternalPlugins
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 030aff7cf..0f2f302f1 100644
--- a/Flow.Launcher.Infrastructure/Http/Http.cs
+++ b/Flow.Launcher.Infrastructure/Http/Http.cs
@@ -16,15 +16,14 @@ namespace Flow.Launcher.Infrastructure.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 @@ namespace Flow.Launcher.Infrastructure.Http
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 1046/1697] 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 27891a2d4..dd79fbc7a 100644
--- a/Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs
@@ -6,6 +6,7 @@ using System.Collections.Generic;
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 @@ namespace Flow.Launcher.Core.ExternalPlugins
///
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 83d4fd9e0..f018bdfc7 100644
--- a/Flow.Launcher.Core/Updater.cs
+++ b/Flow.Launcher.Core/Updater.cs
@@ -93,10 +93,14 @@ namespace Flow.Launcher.Core
}
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 1047/1697] 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 0f2f302f1..12edf34a4 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 @@ namespace Flow.Launcher.Infrastructure.Http
public static HttpProxy Proxy
{
- private get { return proxy; }
+ private get => proxy;
set
{
proxy = value;
@@ -77,7 +79,7 @@ namespace Flow.Launcher.Infrastructure.Http
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 @@ namespace Flow.Launcher.Infrastructure.Http
}
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 @@ namespace Flow.Launcher.Infrastructure.Http
/// 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 @@ namespace Flow.Launcher.Infrastructure.Http
/// 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 @@ namespace Flow.Launcher.Infrastructure.Http
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 @@ namespace Flow.Launcher.Infrastructure.Http
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 9e31d2b4e..a49385a02 100644
--- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
@@ -7,9 +7,8 @@ using System.Threading;
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 @@ namespace Flow.Launcher.Infrastructure.Image
_ = 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 @@ namespace Flow.Launcher.Infrastructure.Image
}
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 @@ namespace Flow.Launcher.Infrastructure.Image
}
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 @@ namespace Flow.Launcher.Infrastructure.Image
{
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 @@ namespace Flow.Launcher.Infrastructure.Image
{
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 807d631c7..25cfbbd3d 100644
--- a/Flow.Launcher.Infrastructure/Logger/Log.cs
+++ b/Flow.Launcher.Infrastructure/Logger/Log.cs
@@ -227,12 +227,6 @@ namespace Flow.Launcher.Infrastructure.Logger
{
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 784d323fe..870e0fe26 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 @@ namespace Flow.Launcher.Infrastructure
///
/// 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 8ff10816c..48e6b5523 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 @@ namespace Flow.Launcher.Infrastructure.Storage
{
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 @@ namespace Flow.Launcher.Infrastructure.Storage
}
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 ca78b2f20..158e0cdf5 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 @@ namespace Flow.Launcher.Infrastructure.Storage
}
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 @@ namespace Flow.Launcher.Infrastructure.Storage
}
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 f283be59e..0b10382ee 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 @@ namespace Flow.Launcher.Infrastructure.Storage
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 d18060e3d..01da96d62 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 @@ namespace Flow.Launcher.Infrastructure.Storage
}
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 @@ namespace Flow.Launcher.Infrastructure.Storage
}
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 e8cbd70fb..147152949 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 @@ namespace Flow.Launcher.Infrastructure.Storage
}
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 @@ namespace Flow.Launcher.Infrastructure.Storage
}
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 1048/1697] Use api functions instead
---
Flow.Launcher.Core/Configuration/Portable.cs | 21 +++++++-------
.../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, 80 insertions(+), 65 deletions(-)
diff --git a/Flow.Launcher.Core/Configuration/Portable.cs b/Flow.Launcher.Core/Configuration/Portable.cs
index 2b570d2c0..7f02cef09 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 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.Infrastructure;
+using Flow.Launcher.Infrastructure.UserSettings;
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 @@ namespace Flow.Launcher.Core.Configuration
}
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 @@ namespace Flow.Launcher.Core.Configuration
}
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 dd79fbc7a..ac27c523c 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;
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 @@ namespace Flow.Launcher.Core.ExternalPlugins
///
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 @@ namespace Flow.Launcher.Core.ExternalPlugins
.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 @@ namespace Flow.Launcher.Core.ExternalPlugins
{
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 bbb6cf638..14796a87a 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
@@ -5,7 +5,6 @@ using System.Linq;
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 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
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 163f97046..f7457b4e1 100644
--- a/Flow.Launcher.Core/Plugin/PluginConfig.cs
+++ b/Flow.Launcher.Core/Plugin/PluginConfig.cs
@@ -3,14 +3,20 @@ using System.Collections.Generic;
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 @@ namespace Flow.Launcher.Core.Plugin
}
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 @@ namespace Flow.Launcher.Core.Plugin
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 @@ namespace Flow.Launcher.Core.Plugin
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 @@ namespace Flow.Launcher.Core.Plugin
}
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 52d6fd736..72303c8b7 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -9,7 +9,6 @@ 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 Flow.Launcher.Plugin.SharedCommands;
@@ -214,12 +213,12 @@ namespace Flow.Launcher.Core.Plugin
() => 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 @@ namespace Flow.Launcher.Core.Plugin
}
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 @@ namespace Flow.Launcher.Core.Plugin
}
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 @@ namespace Flow.Launcher.Core.Plugin
}
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 @@ namespace Flow.Launcher.Core.Plugin
}
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 df841dbbe..1dfc6d4ed 100644
--- a/Flow.Launcher.Core/Resource/Internationalization.cs
+++ b/Flow.Launcher.Core/Resource/Internationalization.cs
@@ -6,7 +6,6 @@ using System.Reflection;
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 @@ namespace Flow.Launcher.Core.Resource
public Internationalization(Settings settings)
{
_settings = settings;
+ _api = Ioc.Default.GetRequiredService();
AddFlowLauncherLanguageDirectory();
SystemLanguageCode = GetSystemLanguageCodeAtStartup();
}
@@ -80,7 +83,7 @@ namespace Flow.Launcher.Core.Resource
}
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 @@ namespace Flow.Launcher.Core.Resource
_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 @@ namespace Flow.Launcher.Core.Resource
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 @@ namespace Flow.Launcher.Core.Resource
}
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 @@ namespace Flow.Launcher.Core.Resource
}
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 @@ namespace Flow.Launcher.Core.Resource
}
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 @@ namespace Flow.Launcher.Core.Resource
}
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 59e76e2d2..64ffec907 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -13,7 +13,6 @@ using System.Windows.Media.Effects;
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 @@ namespace Flow.Launcher.Core.Resource
{
#region Properties & Fields
+ private readonly string ClassName = nameof(Theme);
+
public bool BlurEnabled { get; private set; }
private const string ThemeMetadataNamePrefix = "Name:";
@@ -73,7 +74,7 @@ namespace Flow.Launcher.Core.Resource
}
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 @@ namespace Flow.Launcher.Core.Resource
}
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 @@ namespace Flow.Launcher.Core.Resource
}
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 @@ namespace Flow.Launcher.Core.Resource
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 @@ namespace Flow.Launcher.Core.Resource
}
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 @@ namespace Flow.Launcher.Core.Resource
}
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 f018bdfc7..bc3655f69 100644
--- a/Flow.Launcher.Core/Updater.cs
+++ b/Flow.Launcher.Core/Updater.cs
@@ -12,7 +12,6 @@ using System.Windows;
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 @@ namespace Flow.Launcher.Core
{
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 @@ namespace Flow.Launcher.Core
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 @@ namespace Flow.Launcher.Core
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 @@ namespace Flow.Launcher.Core
{
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 1049/1697] 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 28140f024..b4a3ae47a 100644
--- a/Flow.Launcher/SettingWindow.xaml.cs
+++ b/Flow.Launcher/SettingWindow.xaml.cs
@@ -6,7 +6,6 @@ using System.Windows.Interop;
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 partial class SettingWindow
_settings = Ioc.Default.GetRequiredService();
DataContext = viewModel;
_viewModel = viewModel;
- _api = Ioc.Default.GetRequiredService();
InitializePosition();
InitializeComponent();
}
@@ -49,7 +46,7 @@ public partial class SettingWindow
_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 1050/1697] 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 1dfc6d4ed..b32b09e8f 100644
--- a/Flow.Launcher.Core/Resource/Internationalization.cs
+++ b/Flow.Launcher.Core/Resource/Internationalization.cs
@@ -18,12 +18,15 @@ namespace Flow.Launcher.Core.Resource
{
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 @@ namespace Flow.Launcher.Core.Resource
public Internationalization(Settings settings)
{
_settings = settings;
- _api = Ioc.Default.GetRequiredService();
AddFlowLauncherLanguageDirectory();
SystemLanguageCode = GetSystemLanguageCodeAtStartup();
}
@@ -83,7 +85,7 @@ namespace Flow.Launcher.Core.Resource
}
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 @@ namespace Flow.Launcher.Core.Resource
_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 @@ namespace Flow.Launcher.Core.Resource
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 @@ namespace Flow.Launcher.Core.Resource
}
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 @@ namespace Flow.Launcher.Core.Resource
}
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 @@ namespace Flow.Launcher.Core.Resource
}
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 @@ namespace Flow.Launcher.Core.Resource
}
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 a9cd1a8b9..87677f58a 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -148,8 +148,8 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
_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 @@ namespace Flow.Launcher
AutoUpdates();
API.SaveAppAllSettings();
- Log.Info("|App.OnStartup|End Flow Launcher startup ----------------------------------------------------");
+ API.LogInfo(ClassName, "End Flow Launcher startup ----------------------------------------------------");
});
}
@@ -250,19 +250,19 @@ namespace Flow.Launcher
{
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 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
_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 0d6f2e469..eb492e334 100644
--- a/Flow.Launcher/Converters/QuerySuggestionBoxConverter.cs
+++ b/Flow.Launcher/Converters/QuerySuggestionBoxConverter.cs
@@ -4,13 +4,14 @@ using System.Windows;
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 @@ public class QuerySuggestionBoxConverter : IMultiValueConverter
}
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 c5e20504b..568ea7944 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 class AutoStartup
}
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 @@ public class AutoStartup
}
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 @@ public class AutoStartup
}
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 @@ public class AutoStartup
}
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 @@ public class AutoStartup
}
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 @@ public class AutoStartup
}
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 0771a6074..1e83415cc 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 @@ internal static class HotKeyMapper
}
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 class HotKeyMapper
}
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 class HotKeyMapper
}
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 3d94769d0..a55aeb811 100644
--- a/Flow.Launcher/MessageBoxEx.xaml.cs
+++ b/Flow.Launcher/MessageBoxEx.xaml.cs
@@ -4,13 +4,13 @@ using System.Threading.Tasks;
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 @@ namespace Flow.Launcher
}
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 ff9accd62..110235cb5 100644
--- a/Flow.Launcher/Msg.xaml.cs
+++ b/Flow.Launcher/Msg.xaml.cs
@@ -5,7 +5,6 @@ using System.Windows.Forms;
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 30b3a0673..be81e6ec6 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 @@ namespace Flow.Launcher
{
// 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 2395bdf34..840c8bade 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 @@ namespace Flow.Launcher
}
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 5438eac7d..3abc57b8a 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -435,16 +435,16 @@ namespace Flow.Launcher
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 6fe90783e..0ab785a17 100644
--- a/Flow.Launcher/ReportWindow.xaml.cs
+++ b/Flow.Launcher/ReportWindow.xaml.cs
@@ -8,13 +8,15 @@ 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.UserSettings;
namespace Flow.Launcher
{
internal partial class ReportWindow
{
+ private static readonly string ClassName = nameof(ReportWindow);
+
public ReportWindow(Exception exception)
{
InitializeComponent();
@@ -38,7 +40,7 @@ namespace Flow.Launcher
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 f6b9aa67c..998fdb906 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -16,7 +16,6 @@ using CommunityToolkit.Mvvm.Input;
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 @@ namespace Flow.Launcher.ViewModel
{
#region Private Fields
+ private static readonly string ClassName = nameof(MainViewModel);
+
private bool _isQueryRunning;
private Query _lastQuery;
private string _queryTextBeforeLeaveResults;
@@ -213,7 +214,7 @@ namespace Flow.Launcher.ViewModel
}
if (!_disposed)
- Log.Error("MainViewModel", "Unexpected ResultViewUpdate ends");
+ App.API.LogError(ClassName, "Unexpected ResultViewUpdate ends");
}
void continueAction(Task t)
@@ -257,7 +258,7 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
}
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 8d7569dc1..ef7e24c3b 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.Threading.Tasks;
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 @@ namespace Flow.Launcher.ViewModel
}
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 1051/1697] 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 16b6bcab2..d28845994 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -109,7 +109,6 @@ namespace Flow.Launcher.Plugin.Program
}
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 1052/1697] 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 44d3ef0ff..7ca91eaec 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 @@ namespace Flow.Launcher.Core.ExternalPlugins
}
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 77bebe2d3..93b9a8aaa 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 class WallpaperPathRetrieval
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 class WallpaperPathRetrieval
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 class WallpaperPathRetrieval
}
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 @@ public static class WallpaperPathRetrieval
}
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 3bee49bf2..9ad31ad14 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 class Main : ISettingProvider, IPlugin, IReloadable, IPluginI18n, IContex
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 f47907824..633af7b6b 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 @@ namespace Flow.Launcher.Plugin.Explorer
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 1a0d3bd15..631744252 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 @@ namespace Flow.Launcher.Plugin.Explorer.Search.DirectoryInfo
}
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 4c07341ec..d7f44ccce 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 @@ namespace Flow.Launcher.Plugin.ProcessKiller
}
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 65be06b53..681c8b649 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 @@ namespace Flow.Launcher.Plugin.WebSearch.SuggestionSources
}
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 @@ namespace Flow.Launcher.Plugin.WebSearch.SuggestionSources
}
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 9efc36263..ccfa5dcc8 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 @@ namespace Flow.Launcher.Plugin.WebSearch.SuggestionSources
}
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 1d248caf3..0627f7220 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 @@ namespace Flow.Launcher.Plugin.WebSearch.SuggestionSources
}
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 ad8fb508f..f28212524 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 @@ namespace Flow.Launcher.Plugin.WebSearch.SuggestionSources
}
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 257b0fa8b..c72230f2b 100644
--- a/Plugins/Flow.Launcher.Plugin.WindowsSettings/Log.cs
+++ b/Plugins/Flow.Launcher.Plugin.WindowsSettings/Log.cs
@@ -11,10 +11,12 @@ namespace Flow.Launcher.Plugin.WindowsSettings
{
_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 1053/1697] 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 b67059b1b..62d2d3e91 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/JavaScriptEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/JavaScriptEnvironment.cs
@@ -4,7 +4,6 @@ using Flow.Launcher.Plugin;
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 6c8c5aa57..726bc4cd4 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/JavaScriptV2Environment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/JavaScriptV2Environment.cs
@@ -4,7 +4,6 @@ using Flow.Launcher.Plugin;
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 fab5738de..455ee096d 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs
@@ -5,6 +5,7 @@ using Flow.Launcher.Core.Plugin;
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 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
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 8a4f527ba..12965286f 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs
@@ -5,6 +5,7 @@ using Flow.Launcher.Core.Plugin;
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 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
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 61fd28376..6960b79c9 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs
@@ -5,6 +5,7 @@ using Flow.Launcher.Core.Plugin;
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 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
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 bae263157..7a6bf07e2 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 @@ namespace Flow.Launcher.Core.Plugin
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 @@ namespace Flow.Launcher.Core.Plugin
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 1054/1697] 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 1010d9f08..256c36065 100644
--- a/Flow.Launcher.Core/Plugin/PluginsLoader.cs
+++ b/Flow.Launcher.Core/Plugin/PluginsLoader.cs
@@ -89,19 +89,19 @@ namespace Flow.Launcher.Core.Plugin
#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 25cfbbd3d..09eb98f46 100644
--- a/Flow.Launcher.Infrastructure/Logger/Log.cs
+++ b/Flow.Launcher.Infrastructure/Logger/Log.cs
@@ -94,13 +94,6 @@ namespace Flow.Launcher.Infrastructure.Logger
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 @@ namespace Flow.Launcher.Infrastructure.Logger
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 @@ namespace Flow.Launcher.Infrastructure.Logger
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 998fdb906..00675149b 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -222,7 +222,7 @@ namespace Flow.Launcher.ViewModel
#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 @@ namespace Flow.Launcher.ViewModel
#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 1055/1697] 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 ef7e24c3b..648ac49bb 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 1056/1697] 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 54604a271..6be024389 100644
--- a/Flow.Launcher.Infrastructure/Win32Helper.cs
+++ b/Flow.Launcher.Infrastructure/Win32Helper.cs
@@ -376,7 +376,8 @@ namespace Flow.Launcher.Infrastructure
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 1057/1697] Add sponsor
---
README.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/README.md b/README.md
index cbb553bd1..d8ecfa671 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 1058/1697] 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 8762a934b..9af3b71aa 100644
--- a/Flow.Launcher/HotkeyControl.xaml.cs
+++ b/Flow.Launcher/HotkeyControl.xaml.cs
@@ -243,6 +243,9 @@ namespace Flow.Launcher
}
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 1059/1697] 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 9af3b71aa..262727127 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.Helper;
using Flow.Launcher.Infrastructure.Hotkey;
using Flow.Launcher.Infrastructure.UserSettings;
+#nullable enable
+
namespace Flow.Launcher
{
public partial class HotkeyControl
@@ -242,9 +242,10 @@ namespace Flow.Launcher
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 b89e970e9..916fd1ece 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
@@ -5,7 +5,6 @@ using System.Windows.Controls;
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 @@ public partial class SettingsPanePluginsViewModel : BaseModel
{
var helpDialog = new ContentDialog()
{
+ Owner = Application.Current.MainWindow,
Content = new StackPanel
{
Children =
@@ -146,7 +146,6 @@ public partial class SettingsPanePluginsViewModel : BaseModel
}
}
},
-
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 1060/1697] 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 6be024389..798501ae3 100644
--- a/Flow.Launcher.Infrastructure/Win32Helper.cs
+++ b/Flow.Launcher.Infrastructure/Win32Helper.cs
@@ -365,21 +365,10 @@ namespace Flow.Launcher.Infrastructure
// 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 1061/1697] 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 916fd1ece..de7cf15c3 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
@@ -111,11 +111,11 @@ public partial class SettingsPanePluginsViewModel : BaseModel
.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 f9f708314..f3d630306 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 1062/1697] 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 043eb7a19..39bf49654 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -362,6 +362,7 @@ namespace Flow.Launcher.Plugin.Sys
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 1063/1697] 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 a49385a02..86df01a30 100644
--- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
@@ -171,8 +171,8 @@ namespace Flow.Launcher.Infrastructure.Image
}
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 1064/1697] 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 b98ea50fe..fe389a331 100644
--- a/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs
@@ -12,7 +12,7 @@ using Windows.Win32.Graphics.Gdi;
namespace Flow.Launcher.Infrastructure.Image
{
///
- /// Subclass of
+ /// Subclass of
///
[Flags]
public enum ThumbnailOptions
@@ -33,6 +33,8 @@ namespace Flow.Launcher.Infrastructure.Image
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 @@ namespace Flow.Launcher.Infrastructure.Image
{
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 @@ namespace Flow.Launcher.Infrastructure.Image
// 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 1065/1697] 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 fe389a331..4ce0df026 100644
--- a/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs
@@ -31,7 +31,7 @@ namespace Flow.Launcher.Infrastructure.Image
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 @@ namespace Flow.Launcher.Infrastructure.Image
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 1066/1697] 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 e8d4af8b5..000000000
--- 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 549217027..f13460d3f 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 ff704b679..000000000
--- 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 407300924..cf9ebd33f 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.IO;
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 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
InitializeActionKeywordModels();
}
-
public void Save()
{
Context.API.SaveSettingJsonStorage();
@@ -48,7 +47,6 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
private EnumBindingModel _selectedContentSearchEngine;
private EnumBindingModel _selectedPathEnumerationEngine;
-
public EnumBindingModel SelectedIndexSearchEngine
{
get => _selectedIndexSearchEngine;
@@ -261,8 +259,7 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
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 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
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 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
container.Add(link);
}
+ [RelayCommand]
private void EditLink(object commandParameter)
{
var (selectedLink, collection) = commandParameter switch
@@ -360,7 +352,7 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
Context.API.ShowMsgBox(warning);
}
-
+ [RelayCommand]
private void AddLink(object commandParameter)
{
var container = commandParameter switch
@@ -385,6 +377,7 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
container.Add(newAccessLink);
}
+ [RelayCommand]
private void RemoveLink(object obj)
{
if (obj is not string container) return;
@@ -435,7 +428,6 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
return path;
}
-
internal static void OpenWindowsIndexingOptions()
{
var psi = new ProcessStartInfo
@@ -448,39 +440,35 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
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 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
}
}
-
#region Everything FastSortWarning
public Visibility FastSortWarningVisibility
@@ -593,7 +580,5 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
}
#endregion
-
-
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
index 6ca7be84d..e5999da41 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 1067/1697] 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 0a3a2ae43..72f58f5b6 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 class SortOptionTranslationHelper
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 73c35b1c8..000b2558d 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 @@ namespace Flow.Launcher.Plugin.Explorer.Views
DialogResult = false;
Close();
}
+
private void TxtCurrentActionKeyword_OnKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
@@ -94,11 +95,13 @@ namespace Flow.Launcher.Plugin.Explorer.Views
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 b7f5efc3c..9203ece9a 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 @@ namespace Flow.Launcher.Plugin.Explorer.Views
{
private readonly SettingsViewModel viewModel;
- private List actionKeywordsListView;
-
-
public ExplorerSettings(SettingsViewModel viewModel)
{
DataContext = viewModel;
@@ -39,8 +35,6 @@ namespace Flow.Launcher.Plugin.Explorer.Views
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 1068/1697] 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 110235cb5..923c3692f 100644
--- a/Flow.Launcher/Msg.xaml.cs
+++ b/Flow.Launcher/Msg.xaml.cs
@@ -59,6 +59,7 @@ namespace Flow.Launcher
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 c42bd4f30..deb110698 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 @@ namespace Flow.Launcher.Plugin.Program.Views
programSourceView.Items.Refresh();
}
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD100:Avoid async void methods", Justification = "")]
private async void ReIndexing()
{
ViewRefresh();
@@ -183,6 +184,7 @@ namespace Flow.Launcher.Plugin.Program.Views
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 @@ namespace Flow.Launcher.Plugin.Program.Views
}
}
+ [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 @@ namespace Flow.Launcher.Plugin.Program.Views
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 58577dbc1..b44f130e4 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml.cs
@@ -28,6 +28,7 @@ namespace Flow.Launcher.Plugin.WebSearch
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 @@ namespace Flow.Launcher.Plugin.WebSearch
}
}
+ [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 1069/1697] 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 2f614ead8..d4cd1348e 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 @@ namespace Flow.Launcher.Plugin.Explorer.Views
}
}
}
-}
\ 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 1070/1697] 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 0ab785a17..24801cf52 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 1071/1697] 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 abb76580d..58b4e86f9 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 @@ namespace Peter
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 @@ namespace Peter
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 1072/1697] 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 e526fb85a..6c4e6a3ed 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/EnvironmentVariables.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/EnvironmentVariables.cs
@@ -47,7 +47,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
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 @@ namespace Flow.Launcher.Plugin.Explorer.Search
{
// 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 1073/1697] 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 22de4fcc0..f4c103ade 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 1074/1697] 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 f13460d3f..98164f489 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 1075/1697] 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 f561fcb1d..f0fcd48ff 100644
--- a/Flow.Launcher.Plugin/Result.cs
+++ b/Flow.Launcher.Plugin/Result.cs
@@ -128,12 +128,12 @@ namespace Flow.Launcher.Plugin
///
/// 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 1076/1697] 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 d7f44ccce..386782905 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 @@ namespace Flow.Launcher.Plugin.ProcessKiller
///
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 @@ namespace Flow.Launcher.Plugin.ProcessKiller
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 1077/1697] 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 ea6e54fef..ddabd31f8 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 4f5d1becd..3f505139a 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs
@@ -81,7 +81,9 @@ namespace Flow.Launcher.Plugin.ProcessKiller
// 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 916bc6a39..57cd2ab86 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 bacf1ba08..0728d9c0f 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/ViewModels/SettingsViewModel.cs
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/ViewModels/SettingsViewModel.cs
@@ -9,6 +9,12 @@
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 d15d6c3e0..b969be4e8 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 1078/1697] 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 3f505139a..8f5ba4bd2 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs
@@ -81,7 +81,8 @@ namespace Flow.Launcher.Plugin.ProcessKiller
// 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 @@ namespace Flow.Launcher.Plugin.ProcessKiller
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 @@ namespace Flow.Launcher.Plugin.ProcessKiller
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 @@ namespace Flow.Launcher.Plugin.ProcessKiller
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 1079/1697] 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 0bd1a809b..d91574bdc 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -65,19 +65,21 @@ namespace Flow.Launcher.Infrastructure.UserSettings
{ "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 @@ namespace Flow.Launcher.Infrastructure.UserSettings
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 6cfb98306..abc7a2d16 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 @@ public partial class SettingsPaneAboutViewModel : BaseModel
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 f7deee7cf..b3991743d 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 1080/1697] 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 a73ead814..61711d696 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -228,6 +228,10 @@ namespace Flow.Launcher.Plugin
///
/// 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 1081/1697] 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 61711d696..31580fbe8 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -223,7 +223,7 @@ namespace Flow.Launcher.Plugin
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 @@ namespace Flow.Launcher.Plugin
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 @@ namespace Flow.Launcher.Plugin
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 1082/1697] 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 568ea7944..81568875e 100644
--- a/Flow.Launcher/Helper/AutoStartup.cs
+++ b/Flow.Launcher/Helper/AutoStartup.cs
@@ -3,7 +3,6 @@ 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;
diff --git a/Flow.Launcher/Helper/HotKeyMapper.cs b/Flow.Launcher/Helper/HotKeyMapper.cs
index 1e83415cc..e5fabb3a8 100644
--- a/Flow.Launcher/Helper/HotKeyMapper.cs
+++ b/Flow.Launcher/Helper/HotKeyMapper.cs
@@ -5,7 +5,6 @@ using NHotkey;
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 1083/1697] Fix possible window show issue during startup
---
Flow.Launcher/App.xaml.cs | 11 +---
Flow.Launcher/Helper/AutoStartup.cs | 64 +++++++++++--------
.../SettingsPaneGeneralViewModel.cs | 4 +-
3 files changed, 43 insertions(+), 36 deletions(-)
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 87677f58a..87698a545 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -202,18 +202,11 @@ namespace Flow.Launcher
{
// 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 81568875e..b83bb5948 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,22 +77,28 @@ public class AutoStartup
return false;
}
+ private static bool CheckRegistry()
+ {
+ 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}");
+ }
+
+ return false;
+ }
+
public static void DisableViaLogonTaskAndRegistry()
{
Disable(true);
Disable(false);
}
- public static void EnableViaLogonTask()
- {
- Enable(true);
- }
-
- public static void EnableViaRegistry()
- {
- Enable(false);
- }
-
public static void ChangeToViaLogonTask()
{
Disable(false);
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
index 021c9d7fe..6b56caf5e 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -48,11 +48,11 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
{
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 1084/1697] 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 ac27c523c..6f3b23e11 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 @@ namespace Flow.Launcher.Core.ExternalPlugins
else
{
API.LogWarn(ClassName, $"Failed to load resource {ManifestFileUrl} with response {response.StatusCode}");
- return plugins;
+ return null;
}
}
catch (Exception e)
@@ -83,7 +83,7 @@ namespace Flow.Launcher.Core.ExternalPlugins
{
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 1f23c2f66..bdc1ad3dd 100644
--- a/Flow.Launcher.Core/ExternalPlugins/CommunityPluginStore.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/CommunityPluginStore.cs
@@ -40,10 +40,14 @@ namespace Flow.Launcher.Core.ExternalPlugins
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 1085/1697] 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 0bd1a809b..8500e7aa4 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.Infrastructure.Storage;
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 @@ namespace Flow.Launcher.Infrastructure.UserSettings
{
_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 @@ namespace Flow.Launcher.Infrastructure.UserSettings
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 @@ namespace Flow.Launcher.Infrastructure.UserSettings
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 @@ namespace Flow.Launcher.Infrastructure.UserSettings
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 @@ namespace Flow.Launcher.Infrastructure.UserSettings
}
}
}
- string _placeholderText { get; set; } = string.Empty;
+ private string _placeholderText { get; set; } = string.Empty;
public string PlaceholderText
{
get => _placeholderText;
@@ -373,7 +307,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
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 @@ namespace Flow.Launcher.Infrastructure.UserSettings
Mica,
MicaAlt
}
-
}
diff --git a/Flow.Launcher.Infrastructure/Win32Helper.cs b/Flow.Launcher.Infrastructure/Win32Helper.cs
index 798501ae3..6a5af41df 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.Graphics.Dwm;
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 @@ namespace Flow.Launcher.Infrastructure
}
#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 d62fd906b..1138b2869 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.Plugin.SharedModels;
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 1086/1697] 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 5a6fd3d74..caa9a7129 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 1087/1697] 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 4d765d161..112815ed0 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 1088/1697] 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 17792c0c1..52bc63ec6 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -96,7 +96,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
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 6a5af41df..2788060eb 100644
--- a/Flow.Launcher.Infrastructure/Win32Helper.cs
+++ b/Flow.Launcher.Infrastructure/Win32Helper.cs
@@ -628,21 +628,33 @@ namespace Flow.Launcher.Infrastructure
{ "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 1089/1697] 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 abc7a2d16..ee0865f9d 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 @@ public partial class SettingsPaneAboutViewModel : BaseModel
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 partial class SettingsPaneAboutViewModel : BaseModel
if (_settings.SettingWindowFont != value)
{
_settings.SettingWindowFont = value;
- OnPropertyChanged(nameof(SettingWindowFont));
+ OnPropertyChanged();
}
}
}
@@ -295,26 +285,7 @@ public partial class SettingsPaneAboutViewModel : BaseModel
[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 1090/1697] 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 ee0865f9d..55d6b0a1c 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
@@ -286,6 +286,6 @@ public partial class SettingsPaneAboutViewModel : BaseModel
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 1091/1697] 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 caa9a7129..b66b2ba03 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 b3991743d..44a0490ca 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 1092/1697] 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 0171e6d79..a460ffae0 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 8b193fa1d..c377fb250 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 @@ namespace Flow.Launcher
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 ecbdea606..dcfa572f4 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 @@ namespace Flow.Launcher
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 c12879a04..b16de2770 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 0287af9b0..bfe6914e5 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 b7bda4565..80c0cf1f6 100644
--- a/Flow.Launcher/SelectFileManagerWindow.xaml.cs
+++ b/Flow.Launcher/SelectFileManagerWindow.xaml.cs
@@ -17,6 +17,22 @@ namespace Flow.Launcher
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 1093/1697] 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 000000000..0cb623174
--- /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 1094/1697] 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 0cb623174..2d44e4a2c 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 1095/1697] 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 caa9a7129..8501f083b 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 1096/1697] 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 caa9a7129..8501f083b 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 1097/1697] 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 8501f083b..554e5ed9d 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 1098/1697] "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 8501f083b..554e5ed9d 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 790c9d2c6..ee6b4379d 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 1099/1697] 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 554e5ed9d..f1b41eb3c 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 0b5de1280..f7853515a 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 1100/1697] 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 718a28dbd..7498262de 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 1101/1697] 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 bf7a45b1d..ee84dfeb4 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -138,8 +138,12 @@ namespace Flow.Launcher
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 1102/1697] 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 b6fd9555b..4468b7865 100644
--- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
+++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
@@ -58,11 +58,5 @@ public partial class SettingWindowViewModel : BaseModel
}
}
}
-
- 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 1103/1697] 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 70b5a22ed..b4a3ae47a 100644
--- a/Flow.Launcher/SettingWindow.xaml.cs
+++ b/Flow.Launcher/SettingWindow.xaml.cs
@@ -3,7 +3,6 @@ using System.Windows;
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 1104/1697] 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 dcfa572f4..ba326fb9e 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 1105/1697] 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 55d6b0a1c..acffe1e85 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
@@ -285,7 +285,6 @@ public partial class SettingsPaneAboutViewModel : BaseModel
[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 1106/1697] 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 52bc63ec6..0f878151e 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -96,7 +96,6 @@ namespace Flow.Launcher.Infrastructure.UserSettings
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 @@ namespace Flow.Launcher.Infrastructure.UserSettings
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 a460ffae0..d3c31c6da 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 c377fb250..3c501d41a 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 @@ namespace Flow.Launcher
{
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 @@ namespace Flow.Launcher
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 9256a2c52..cbdcecea6 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 ba326fb9e..183cc3a7f 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 b16de2770..4fc5a91c5 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 e8365819b..849056ab1 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
{
+ public Settings Settings { get; }
+
private int selectedCustomBrowserIndex;
- 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));
- }
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 @@ namespace Flow.Launcher
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 bfe6914e5..7d1fe0f56 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 80c0cf1f6..946052e32 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 @@ namespace Flow.Launcher
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 44a0490ca..4bf5df227 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 cedc19633..1ecc02aa6 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 @@ public partial class SettingsPaneAbout
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 f2cf9fab2..a34777d30 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 4468b7865..19edba4d9 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 partial class SettingWindowViewModel : BaseModel
///
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 1107/1697] 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 3c501d41a..cc07caaa2 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 183cc3a7f..fcee0c961 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 19edba4d9..f05893cf4 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 1108/1697] 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 ef85e8724..251d74c14 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 1ec01f8d1..3fd66d623 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 1109/1697] 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 0f878151e..ca015fd70 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 @@ namespace Flow.Launcher.Infrastructure.UserSettings
{
_settingWindowFont = value;
OnPropertyChanged();
+ Application.Current.Resources["SettingWindowFont"] = new FontFamily(value);
}
}
}
diff --git a/Flow.Launcher/CustomQueryHotkeySetting.xaml b/Flow.Launcher/CustomQueryHotkeySetting.xaml
index d3c31c6da..0171e6d79 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 cbdcecea6..d8623753f 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 04a26f09c..72897521b 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 ef85e8724..be68fc1b1 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/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/CustomBrowserSetting.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/CustomBrowserSetting.xaml
index f5017ced5..80b004ff9 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 37a7ccb8d..ae0f91d93 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 9848f51cf..26efc6813 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 71bc12a86..53baa79a3 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 1116/1697] 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 | 67 ++++++++++++-------
Flow.Launcher/SelectBrowserWindow.xaml.cs | 15 +++--
Flow.Launcher/SelectFileManagerWindow.xaml.cs | 15 +++--
.../SettingsPaneGeneralViewModel.cs | 3 +-
.../SettingsPanePluginStoreViewModel.cs | 1 -
12 files changed, 121 insertions(+), 83 deletions(-)
diff --git a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
index cc07caaa2..77febde9d 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 @@ namespace Flow.Launcher
{
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 @@ namespace Flow.Launcher
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 fcee0c961..e180f6570 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 9b19ffd86..bc167184b 100644
--- a/Flow.Launcher/Resources/Controls/HotkeyDisplay.xaml.cs
+++ b/Flow.Launcher/Resources/Controls/HotkeyDisplay.xaml.cs
@@ -42,14 +42,11 @@ namespace Flow.Launcher.Resources.Controls
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 64f52edff..a3b008206 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 786b4d506..a63edbcda 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 f59b65c1c..4a6610e61 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 4c83f3a83..1ee3284d2 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 95d7ff1a0..6328c9914 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();
- }
- private void OnAutoStartupUncheck(object sender, RoutedEventArgs e)
- {
- RemoveStartup();
+ ChangeAutoStartup(true);
}
- private void RemoveStartup()
+ private void OnAutoStartupUncheck(object sender, RoutedEventArgs e)
{
- using var key = Registry.CurrentUser.OpenSubKey(StartupPath, true);
- key?.DeleteValue(Constant.FlowLauncher, false);
- Settings.StartFlowLauncherOnSystemStartup = false;
+ ChangeAutoStartup(false);
}
- private void SetStartup()
+
+ private void ChangeAutoStartup(bool value)
{
- 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 @@ namespace Flow.Launcher.Resources.Pages
var window = Window.GetWindow(this);
window.Close();
}
-
}
}
diff --git a/Flow.Launcher/SelectBrowserWindow.xaml.cs b/Flow.Launcher/SelectBrowserWindow.xaml.cs
index 849056ab1..bea5b4352 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 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
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 946052e32..bf94ddacb 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 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
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 6b56caf5e..c8b83c730 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 partial class SettingsPaneGeneralViewModel : BaseModel
{
try
{
- if (UseLogonTaskForStartup)
+ if (value)
{
AutoStartup.ChangeToViaLogonTask();
}
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs
index fd2c8e09f..68c69f841 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 1117/1697] 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 6a7b892be..ba0f4e5ed 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -201,6 +201,10 @@ namespace Flow.Launcher
#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 1118/1697] 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 ba0f4e5ed..e91676b7b 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -147,6 +147,10 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
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 1119/1697] 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 e91676b7b..ac134fb5f 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -154,7 +154,7 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
}
///
- /// 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 @@ namespace Flow.Launcher
}
///
- /// 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 @@ namespace Flow.Launcher
}
///
- /// 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 1120/1697] 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 38a6ef31e..6cddee8d8 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);
+ var handler = new HttpClientHandler
+ {
+ Proxy = new WebProxy(Settings.Proxy.Server, Settings.Proxy.Port)
+ };
- if (string.IsNullOrEmpty(Settings.Proxy.UserName) || string.IsNullOrEmpty(Settings.Proxy.Password))
+ if (!string.IsNullOrEmpty(Settings.Proxy.UserName) && !string.IsNullOrEmpty(Settings.Proxy.Password))
{
- request.Proxy = new WebProxy(Settings.Proxy.Server, Settings.Proxy.Port);
- }
- else
- {
- 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 1121/1697] 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 1138b2869..d542eb019 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
@@ -6,7 +6,6 @@ using System.Globalization;
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 partial class SettingsPaneThemeViewModel : BaseModel
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 partial class SettingsPaneThemeViewModel : BaseModel
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 f7853515a..4640165f6 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 f4c103ade..a1a0231a5 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 @@ public partial class SettingsPaneTheme : Page
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 1122/1697] 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 e0a217251..32ee3c043 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
@@ -113,7 +113,7 @@ namespace Flow.Launcher.Core.Plugin
// 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 @@ namespace Flow.Launcher.Core.Plugin
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 1123/1697] 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 1cccc38d9..c7a973b2f 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -116,6 +116,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
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 1124/1697] 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 c7a973b2f..e623ba400 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -113,7 +113,6 @@ namespace Flow.Launcher.Infrastructure.UserSettings
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 1125/1697] 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 a34777d30..ab27b235a 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 1126/1697] 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 32ee3c043..003e72a5d 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
@@ -154,7 +154,7 @@ namespace Flow.Launcher.Core.Plugin
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 1127/1697] 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 ac134fb5f..20dd50668 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -19,6 +19,7 @@ using Flow.Launcher.Infrastructure.Logger;
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 @@ namespace Flow.Launcher
.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 c8b83c730..1a887c4b7 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 1ecc02aa6..e57cba6d4 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 @@ public partial class SettingsPaneAbout
{
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 569d489d2..31653962d 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 @@ public partial class SettingsPaneGeneral
{
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 eb100da0c..8b757bd60 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 @@ public partial class SettingsPaneHotkey
{
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 3bd24bc13..131dfab6d 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml.cs
@@ -5,7 +5,6 @@ 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;
@@ -17,8 +16,7 @@ public partial class SettingsPanePluginStore
{
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 f6b435186..97574b3ce 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 @@ public partial class SettingsPanePlugins
{
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 26350b8bb..258f2a4ad 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 @@ public partial class SettingsPaneProxy
{
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 a1a0231a5..cee8e4ae4 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 @@ public partial class SettingsPaneTheme : Page
{
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 f05893cf4..0fe4557a7 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 partial class SettingWindowViewModel : BaseModel
///
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 5eecabfde..82d19273f 100644
--- a/Flow.Launcher/ViewModel/WelcomeViewModel.cs
+++ b/Flow.Launcher/ViewModel/WelcomeViewModel.cs
@@ -18,6 +18,7 @@ namespace Flow.Launcher.ViewModel
{
_pageNum = value;
OnPropertyChanged();
+ OnPropertyChanged(nameof(PageDisplay));
UpdateView();
}
}
@@ -47,7 +48,6 @@ namespace Flow.Launcher.ViewModel
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 1128/1697] 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 e623ba400..cf194b366 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -115,7 +115,6 @@ namespace Flow.Launcher.Infrastructure.UserSettings
_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 bf7a45b1d..ae05d1124 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -140,7 +140,8 @@ namespace Flow.Launcher
_viewModel.Show();
}
- // Show notify icon when flowlauncher is hidden
+ // Initialize context menu & notify icon
+ InitializeContextMenu();
InitializeNotifyIcon();
// Initialize color scheme
@@ -270,6 +271,9 @@ namespace Flow.Launcher
case nameof(Settings.KeepMaxResults):
SetupResizeMode();
break;
+ case nameof(Settings.SettingWindowFont):
+ InitializeContextMenu();
+ break;
}
};
@@ -563,6 +567,44 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
_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 1129/1697] 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 cf194b366..1cccc38d9 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -113,6 +113,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
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 1130/1697] 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 20dd50668..b1ff136b3 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -79,12 +79,16 @@ namespace Flow.Launcher
.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 1131/1697] 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 b4a3ae47a..cd3e5414f 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.Infrastructure.UserSettings;
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 @@ public partial class SettingWindow
_settings.SettingWindowState = WindowState;
_settings.SettingWindowTop = Top;
_settings.SettingWindowLeft = Left;
- _viewModel.Save();
+ _settings.Save();
App.API.SavePluginSettings();
}
@@ -104,7 +114,11 @@ public partial class SettingWindow
RefreshMaximizeRestoreButton();
}
- public void InitializePosition()
+ #endregion
+
+ #region Window Position
+
+ public void UpdatePositionAndState()
{
var previousTop = _settings.SettingWindowTop;
var previousLeft = _settings.SettingWindowLeft;
@@ -119,6 +133,7 @@ public partial class SettingWindow
Top = previousTop.Value;
Left = previousLeft.Value;
}
+
WindowState = _settings.SettingWindowState;
}
@@ -155,6 +170,10 @@ public partial class SettingWindow
return top;
}
+ #endregion
+
+ #region Navigation View Events
+
private void NavigationView_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
{
if (args.IsSettingsSelected)
@@ -201,4 +220,6 @@ public partial class SettingWindow
{
NavView.SelectedItem ??= NavView.MenuItems[0]; /* Set First Page */
}
+
+ #endregion
}
diff --git a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
index 0fe4557a7..17a1a2b50 100644
--- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
+++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
@@ -12,14 +12,6 @@ public partial class SettingWindowViewModel : BaseModel
_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 637f9448d..d23bd4937 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 @@ namespace Flow.Launcher
public WelcomeWindow()
{
+ _settings = Ioc.Default.GetRequiredService();
_viewModel = Ioc.Default.GetRequiredService();
DataContext = _viewModel;
InitializeComponent();
@@ -97,7 +99,7 @@ namespace Flow.Launcher
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 1132/1697] 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 ae05d1124..381d03c1f 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -324,7 +324,7 @@ namespace Flow.Launcher
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 1133/1697] 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 b1ff136b3..1b57d5cbe 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -31,6 +31,7 @@ namespace Flow.Launcher
#region Public Properties
public static IPublicAPI API { get; private set; }
+ public static bool Exiting => _mainWindow.CanClose;
#endregion
@@ -39,7 +40,7 @@ namespace Flow.Launcher
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 ab27b235a..a75a51c8f 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 cd3e5414f..79bd171ed 100644
--- a/Flow.Launcher/SettingWindow.xaml.cs
+++ b/Flow.Launcher/SettingWindow.xaml.cs
@@ -52,9 +52,9 @@ public partial class SettingWindow
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 @@ public partial class SettingWindow
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 @@ public partial class SettingWindow
}
}
- 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 d23bd4937..ef0706765 100644
--- a/Flow.Launcher/WelcomeWindow.xaml.cs
+++ b/Flow.Launcher/WelcomeWindow.xaml.cs
@@ -78,10 +78,7 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
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 1134/1697] 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 60655fa7c..fc9246aa3 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 1142/1697] 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 1143/1697] 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 7867fa980..66c1cb1bf 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 1144/1697] 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 66c1cb1bf..fde022da7 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 1145/1697] 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 fde022da7..df9cc3556 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 1146/1697] 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 df9cc3556..9312b0c2d 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 1147/1697] 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 ad24f2a76..9420b4c38 100644
--- a/Flow.Launcher/ActionKeywords.xaml.cs
+++ b/Flow.Launcher/ActionKeywords.xaml.cs
@@ -80,7 +80,7 @@ namespace Flow.Launcher
}
// 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 8312806fb..64a7f3db8 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -155,16 +155,11 @@ namespace Flow.Launcher.ViewModel
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 1148/1697] 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 f02b2297f..31547200b 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 1472813b8..ce3b7ab1a 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 91cab9fa0..8d43eff98 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 1149/1697] 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 231d14d55..3889b9b00 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
@@ -186,6 +186,7 @@ public partial class SettingsPaneAboutViewModel : BaseModel
{
try
{
+ // Make sure directory clean
dir.Delete(true);
}
catch (Exception e)
@@ -214,6 +215,7 @@ public partial class SettingsPaneAboutViewModel : BaseModel
{
var success = true;
var cacheDirectory = GetCacheDir();
+ var pluginCacheDirectory = GetPluginCacheDir();
var cacheFiles = GetCacheFiles();
cacheFiles.ForEach(f =>
@@ -229,12 +231,31 @@ public partial class SettingsPaneAboutViewModel : BaseModel
}
});
+ // 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 @@ public partial class SettingsPaneAboutViewModel : BaseModel
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 1150/1697] 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 3889b9b00..652fc1ce5 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
@@ -186,8 +186,8 @@ public partial class SettingsPaneAboutViewModel : BaseModel
{
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 @@ public partial class SettingsPaneAboutViewModel : BaseModel
});
// 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 1151/1697] 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 652fc1ce5..374dcb3ad 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
@@ -187,7 +187,7 @@ public partial class SettingsPaneAboutViewModel : BaseModel
try
{
// Log folders are the last level of folders
- dir.Delete(false);
+ dir.Delete(recursive: false);
}
catch (Exception e)
{
@@ -239,7 +239,7 @@ public partial class SettingsPaneAboutViewModel : BaseModel
try
{
// Plugin may create directories in its cache directory
- dir.Delete(true);
+ dir.Delete(recursive: true);
}
catch (Exception e)
{
@@ -249,10 +249,11 @@ public partial class SettingsPaneAboutViewModel : BaseModel
});
// 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 1152/1697] 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 374dcb3ad..00f40b009 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
@@ -252,7 +252,6 @@ public partial class SettingsPaneAboutViewModel : BaseModel
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 1153/1697] 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 7f35904a5..63f0a2fce 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 00675149b..54ad6c288 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -37,11 +37,10 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
_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 @@ namespace Flow.Launcher.ViewModel
{
_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 1154/1697] 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 0b10382ee..20aacb344 100644
--- a/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
@@ -45,6 +45,11 @@ namespace Flow.Launcher.Infrastructure.Storage
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 63f0a2fce..25774a2c0 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 @@ namespace Flow.Launcher.Storage
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 @@ namespace Flow.Launcher.Storage
}
}
+ 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 1155/1697] 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 20aacb344..db9ccc28a 100644
--- a/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
@@ -50,6 +50,22 @@ namespace Flow.Launcher.Infrastructure.Storage
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 25774a2c0..f7459dc40 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();
- // Convert to new data
- _topMostRecordStorage = new FlowLauncherJsonStorage();
+ // Check if data exist
+ var oldDataExist = topMostRecordStorage.Exists();
+ var newDataExist = _topMostRecordStorage.Exists();
+
+ // 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 @@ namespace Flow.Launcher.Storage
public class MultipleTopMostRecord
{
[JsonInclude]
+ [JsonConverter(typeof(ConcurrentDictionaryConcurrentBagConverter))]
public ConcurrentDictionary> records { get; private set; } = new();
internal void Add(TopMostRecord topMostRecord)
@@ -207,6 +237,30 @@ namespace Flow.Launcher.Storage
}
}
+ 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 1156/1697] 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 f7459dc40..aaf7194e7 100644
--- a/Flow.Launcher/Storage/TopMostRecord.cs
+++ b/Flow.Launcher/Storage/TopMostRecord.cs
@@ -188,6 +188,12 @@ namespace Flow.Launcher.Storage
{
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 1157/1697] 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 aaf7194e7..d604eabc1 100644
--- a/Flow.Launcher/Storage/TopMostRecord.cs
+++ b/Flow.Launcher/Storage/TopMostRecord.cs
@@ -243,6 +243,9 @@ namespace Flow.Launcher.Storage
}
}
+ ///
+ /// 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 1158/1697] 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 d604eabc1..7c45bcf66 100644
--- a/Flow.Launcher/Storage/TopMostRecord.cs
+++ b/Flow.Launcher/Storage/TopMostRecord.cs
@@ -34,7 +34,7 @@ namespace Flow.Launcher.Storage
}
catch
{
- // Ignored
+ // Ignored - Flow will delete the old data during next startup
}
_topMostRecord = _topMostRecordStorage.Load();
}
@@ -52,7 +52,7 @@ namespace Flow.Launcher.Storage
}
catch
{
- // Ignored
+ // Ignored - Flow will delete the old data during next startup
}
Save();
}
@@ -84,7 +84,10 @@ namespace Flow.Launcher.Storage
}
}
- 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 @@ namespace Flow.Launcher.Storage
}
}
- 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 @@ namespace Flow.Launcher.Storage
///
/// 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 @@ namespace Flow.Launcher.Storage
}
}
- public class Record
+ internal class Record
{
public string Title { get; init; }
public string SubTitle { get; init; }
From 4ecef470e82c07c611044db777675e5205bede6d Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 1 May 2025 13:33:24 +0800
Subject: [PATCH 1159/1697] 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 db9ccc28a..c7eba05fd 100644
--- a/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
@@ -52,17 +52,12 @@ namespace Flow.Launcher.Infrastructure.Storage
public void Delete()
{
- if (File.Exists(FilePath))
+ foreach (var path in new[] { FilePath, BackupFilePath, TempFilePath })
{
- File.Delete(FilePath);
- }
- if (File.Exists(BackupFilePath))
- {
- 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 1160/1697] 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 7c45bcf66..0a9921f73 100644
--- a/Flow.Launcher/Storage/TopMostRecord.cs
+++ b/Flow.Launcher/Storage/TopMostRecord.cs
@@ -189,11 +189,8 @@ namespace Flow.Launcher.Storage
}
// 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 @@ namespace Flow.Launcher.Storage
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 1161/1697] 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 0a9921f73..47ebb4a95 100644
--- a/Flow.Launcher/Storage/TopMostRecord.cs
+++ b/Flow.Launcher/Storage/TopMostRecord.cs
@@ -190,13 +190,16 @@ namespace Flow.Launcher.Storage
// 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 1162/1697] 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 47ebb4a95..7ddca721b 100644
--- a/Flow.Launcher/Storage/TopMostRecord.cs
+++ b/Flow.Launcher/Storage/TopMostRecord.cs
@@ -16,8 +16,10 @@ namespace Flow.Launcher.Storage
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 @@ namespace Flow.Launcher.Storage
{
// 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 @@ namespace Flow.Launcher.Storage
///
/// 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 @@ namespace Flow.Launcher.Storage
[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 1163/1697] 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 7ddca721b..d75e9cb79 100644
--- a/Flow.Launcher/Storage/TopMostRecord.cs
+++ b/Flow.Launcher/Storage/TopMostRecord.cs
@@ -49,9 +49,11 @@ namespace Flow.Launcher.Storage
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 @@ namespace Flow.Launcher.Storage
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 @@ namespace Flow.Launcher.Storage
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 @@ namespace Flow.Launcher.Storage
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 @@ namespace Flow.Launcher.Storage
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 @@ namespace Flow.Launcher.Storage
};
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 54ad6c288..adb04279e 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1643,9 +1643,10 @@ namespace Flow.Launcher.ViewModel
{
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 1164/1697] 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 adb04279e..96e039ebe 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1646,6 +1646,8 @@ namespace Flow.Launcher.ViewModel
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 1165/1697] 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 | 207 ++++++++++++------
19 files changed, 444 insertions(+), 160 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/QueryBuilder.cs b/Flow.Launcher.Core/Plugin/QueryBuilder.cs
index 3dc7877ac..0ef3f30f5 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 @@ namespace Flow.Launcher.Core.Plugin
searchTerms = terms;
}
- return new Query ()
+ return new Query()
{
Search = search,
RawQuery = rawQuery,
@@ -42,4 +42,4 @@ namespace Flow.Launcher.Core.Plugin
};
}
}
-}
\ No newline at end of file
+}
diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs
index a46932c6a..059359694 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -76,7 +76,7 @@ namespace Flow.Launcher.Core.Resource
{
_api.LogError(ClassName, "Current theme resource not found. Initializing with default theme.");
_oldTheme = Constant.DefaultTheme;
- };
+ }
}
#endregion
@@ -126,7 +126,7 @@ namespace Flow.Launcher.Core.Resource
// 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 @@ namespace Flow.Launcher.Core.Resource
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 @@ namespace Flow.Launcher.Core.Resource
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 @@ namespace Flow.Launcher.Core.Resource
// 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 @@ namespace Flow.Launcher.Core.Resource
{
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 @@ namespace Flow.Launcher.Core.Resource
// 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 18b206022..0e50420b0 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 71020369a..2d15b54c5 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 @@ namespace Flow.Launcher.Infrastructure.UserSettings
}
}
- 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 @@ namespace Flow.Launcher.Infrastructure.UserSettings
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 1cccc38d9..b7a1d1f63 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -312,9 +312,9 @@ namespace Flow.Launcher.Infrastructure.UserSettings
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 2788060eb..783ade14e 100644
--- a/Flow.Launcher.Infrastructure/Win32Helper.cs
+++ b/Flow.Launcher.Infrastructure/Win32Helper.cs
@@ -5,6 +5,8 @@ using System.Diagnostics;
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 @@ namespace Flow.Launcher.Infrastructure
#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 31580fbe8..d4eb02a90 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -471,8 +471,11 @@ namespace Flow.Launcher.Plugin
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 913dc31ae..c3eede4c6 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 @@ namespace Flow.Launcher.Plugin
///
[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 1b57d5cbe..402812a92 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -23,6 +23,7 @@ using Flow.Launcher.SettingPages.ViewModels;
using Flow.Launcher.ViewModel;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
+using Microsoft.VisualStudio.Threading;
namespace Flow.Launcher
{
@@ -198,6 +199,10 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
}
}
+ [Conditional("RELEASE")]
private void AutoUpdates()
{
_ = Task.Run(async () =>
@@ -296,13 +302,12 @@ namespace Flow.Launcher
[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 2e72ee240..db198ede4 100644
--- a/Flow.Launcher/Helper/DataWebRequestFactory.cs
+++ b/Flow.Launcher/Helper/DataWebRequestFactory.cs
@@ -28,18 +28,18 @@ public class DataWebRequestFactory : IWebRequestCreate
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 class DataWebRequestFactory : IWebRequestCreate
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 b1ddba717..aa810ba65 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 d3252cb31..ca0ed33b5 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 10aff050e..ae7b098a2 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -16,7 +16,6 @@ using System.Windows.Threading;
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 @@ namespace Flow.Launcher
// 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 3abc57b8a..5b8e8c9af 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -40,7 +40,7 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
_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 @@ namespace Flow.Launcher
UpdateManager.RestartApp(Constant.ApplicationFileName);
}
-#pragma warning restore VSTHRD100 // Avoid async void methods
-
public void ShowMainWindow() => _mainVM.Show();
public void HideMainWindow() => _mainVM.Hide();
@@ -145,37 +142,92 @@ namespace Flow.Launcher
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 (showDefaultNotification)
- ShowMsg(
- $"{GetTranslation("copy")} {GetTranslation("textTitle")}",
- GetTranslation("completedSuccessfully"));
+ 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"));
+ }
}
}
+ 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;
public void StopLoadingBar() => _mainVM.ProgressBarVisibility = Visibility.Collapsed;
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs
index 249e4dd42..07df0682d 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs
@@ -79,8 +79,8 @@ public partial class SettingsPanePluginStoreViewModel : BaseModel
}
}
- 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 de7cf15c3..abb314355 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
@@ -86,12 +86,22 @@ public partial class SettingsPanePluginsViewModel : BaseModel
UpdateEnumDropdownLocalizations();
}
- public string FilterText { get; set; } = string.Empty;
+ private string filterText = string.Empty;
+ public string FilterText
+ {
+ get => filterText;
+ set
+ {
+ if (filterText != value)
+ {
+ filterText = value;
+ OnPropertyChanged();
+ }
+ }
+ }
- public PluginViewModel? SelectedPlugin { get; set; }
-
- 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 partial class SettingsPanePluginsViewModel : BaseModel
.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 bb742f800..52d77f914 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 97574b3ce..e9490804a 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 @@ public partial class SettingsPanePlugins
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 00675149b..2f1ed0f51 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -43,8 +43,7 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
}
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 @@ namespace Flow.Launcher.ViewModel
/// 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 @@ namespace Flow.Launcher.ViewModel
///
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 @@ namespace Flow.Launcher.ViewModel
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,20 +1197,45 @@ namespace Flow.Launcher.ViewModel
{
_updateSource?.Cancel();
- var query = ConstructQuery(QueryText, Settings.CustomShortcuts, Settings.BuiltinShortcuts);
+ var query = await ConstructQueryAsync(QueryText, Settings.CustomShortcuts, Settings.BuiltinShortcuts);
- var plugins = PluginManager.ValidPluginsForQuery(query);
-
- 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)
+
+ _updateSource = new CancellationTokenSource();
+
+ ProgressBarVisibility = Visibility.Hidden;
+ _isQueryRunning = true;
+
+ // Switch to ThreadPool thread
+ await TaskScheduler.Default;
+
+ if (_updateSource.Token.IsCancellationRequested) return;
+
+ // 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);
+
+ _lastQuery = query;
+
+ var plugins = PluginManager.ValidPluginsForQuery(query);
+
+ if (plugins.Count == 1)
{
PluginIconPath = plugins.Single().Metadata.IcoPath;
PluginIconSource = await App.API.LoadImageAsync(PluginIconPath);
@@ -1186,42 +1248,20 @@ namespace Flow.Launcher.ViewModel
SearchIconVisibility = Visibility.Visible;
}
- _updateSource?.Dispose();
-
- var currentUpdateSource = new CancellationTokenSource();
- _updateSource = currentUpdateSource;
- _updateToken = _updateSource.Token;
-
- ProgressBarVisibility = Visibility.Hidden;
- _isQueryRunning = true;
-
- // Switch to ThreadPool thread
- await TaskScheduler.Default;
-
- if (_updateSource.Token.IsCancellationRequested)
- return;
-
- // 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);
-
- _lastQuery = query;
-
- if (string.IsNullOrEmpty(query.ActionKeyword))
+ // 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 @@ namespace Flow.Launcher.ViewModel
// 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 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
}
}
+ if (token.IsCancellationRequested) return;
+
if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(resultsCopy, plugin.Metadata, query,
token, reSelect)))
{
@@ -1309,16 +1349,16 @@ namespace Flow.Launcher.ViewModel
}
}
- 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 @@ namespace Flow.Launcher.ViewModel
queryBuilder.Replace('@' + shortcut.Key, shortcut.Expand());
}
- string customExpanded = queryBuilder.ToString();
+ // Applying builtin shortcuts
+ await BuildQueryAsync(builtInShortcuts, queryBuilder, queryBuilderTmp);
- Application.Current.Dispatcher.Invoke(() =>
+ 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;
+
+ 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;
}
}
- });
+ catch (Exception e)
+ {
+ App.API.LogException(ClassName, $"Error when expanding shortcut {shortcut.Key}", e);
+ }
+ }
- // show expanded builtin shortcuts
- // use private field to avoid infinite recursion
- _queryText = queryBuilderTmp.ToString();
-
- 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 @@ namespace Flow.Launcher.ViewModel
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 1166/1697] 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 2f1ed0f51..2526adef8 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1170,7 +1170,7 @@ namespace Flow.Launcher.ViewModel
OriginQuery = new Query { RawQuery = h.Query },
Action = _ =>
{
- SelectedResults = Results;
+ App.API.BackToQueryResults();
App.API.ChangeQuery(h.Query);
return false;
}
@@ -1600,10 +1600,7 @@ namespace Flow.Launcher.ViewModel
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 1167/1697] 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 2526adef8..f0513c7d9 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -34,6 +34,7 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
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 1168/1697] 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 f0513c7d9..607b70fd2 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1432,10 +1432,10 @@ namespace Flow.Launcher.ViewModel
}
}
+ // 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 1169/1697] 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 607b70fd2..c505c32a3 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1437,6 +1437,9 @@ namespace Flow.Launcher.ViewModel
{
// 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 1170/1697] 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 a18f0848d..f7a820f18 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 4ebdcf1fd..f3c9cfcad 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 @@ namespace Flow.Launcher.Plugin
///
///
///
- 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 1171/1697] 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 05e8d960f..48717816b 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginIndicator/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginIndicator/Main.cs
@@ -3,21 +3,33 @@ using System.Linq;
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 1172/1697] 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 f7a820f18..78d6454ae 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 1173/1697] 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 72303c8b7..b0f896214 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -25,6 +25,7 @@ namespace Flow.Launcher.Core.Plugin
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 @@ namespace Flow.Launcher.Core.Plugin
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 @@ namespace Flow.Launcher.Core.Plugin
};
}
+ 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 @@ namespace Flow.Launcher.Core.Plugin
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 @@ namespace Flow.Launcher.Core.Plugin
}
}
+ 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 b7a1d1f63..2b5fc6bc0 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -158,6 +158,11 @@ namespace Flow.Launcher.Infrastructure.UserSettings
}
}
}
+
+ 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 f0fcd48ff..060c03317 100644
--- a/Flow.Launcher.Plugin/Result.cs
+++ b/Flow.Launcher.Plugin/Result.cs
@@ -174,6 +174,9 @@ namespace Flow.Launcher.Plugin
///
/// 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 2f1ed0f51..b5afe4b7e 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1198,21 +1198,31 @@ namespace Flow.Launcher.ViewModel
_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 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
// 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 @@ namespace Flow.Launcher.ViewModel
// 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 @@ namespace Flow.Launcher.ViewModel
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 1174/1697] 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 ae7b098a2..546f32cc5 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -292,6 +292,9 @@ namespace Flow.Launcher
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 b5afe4b7e..8244d5765 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1074,6 +1074,14 @@ namespace Flow.Launcher.ViewModel
#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 1175/1697] 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 2b5fc6bc0..b630a4ecc 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -159,9 +159,9 @@ namespace Flow.Launcher.Infrastructure.UserSettings
}
}
- 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 8244d5765..06cce3026 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1076,7 +1076,7 @@ namespace Flow.Launcher.ViewModel
public void InitializeQuery()
{
- if (Settings.ShowHomeQuery)
+ if (Settings.ShowHomePage)
{
_ = QueryResultsAsync(false);
}
@@ -1211,7 +1211,7 @@ namespace Flow.Launcher.ViewModel
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 1176/1697] 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 ca0ed33b5..af718946d 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 1a887c4b7..840269b03 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -154,11 +154,22 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
{
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 d45d28d8b..c0c5613de 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 1177/1697] 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 06cce3026..d850e0f7c 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -50,6 +50,12 @@ namespace Flow.Launcher.ViewModel
private readonly IReadOnlyList _emptyResult = new List();
+ private readonly PluginMetadata _historyMetadata = new()
+ {
+ ID = "298303A65D128A845D28A7B83B3968C2",
+ Priority = 0
+ };
+
#endregion
#region Constructor
@@ -1300,11 +1306,30 @@ namespace Flow.Launcher.ViewModel
// 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 @@ namespace Flow.Launcher.ViewModel
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 1178/1697] 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 b0f896214..caa3fd00b 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -221,6 +221,7 @@ namespace Flow.Launcher.Core.Plugin
{
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 @@ namespace Flow.Launcher.Core.Plugin
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 7fb9b895a..837d0ebb6 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/PluginSettings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/PluginSettings.cs
@@ -67,6 +67,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
metadata.Disabled = settings.Disabled;
metadata.Priority = settings.Priority;
metadata.SearchDelayTime = settings.SearchDelayTime;
+ metadata.HomeDisabled = settings.HomeDiabled;
}
else
{
@@ -79,6 +80,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
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 @@ namespace Flow.Launcher.Infrastructure.UserSettings
/// 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 da10bc6a5..09803cbd7 100644
--- a/Flow.Launcher.Plugin/PluginMetadata.cs
+++ b/Flow.Launcher.Plugin/PluginMetadata.cs
@@ -50,6 +50,11 @@ namespace Flow.Launcher.Plugin
///
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 af718946d..22ab2016c 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 619da22dc..0842a64f3 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 @@ public partial class SettingsPanePluginsViewModel : BaseModel
{
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 @@ public partial class SettingsPanePluginsViewModel : BaseModel
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 64a7f3db8..092896019 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -75,6 +75,16 @@ namespace Flow.Launcher.ViewModel
}
}
+ public bool PluginHomeState
+ {
+ get => !PluginPair.Metadata.HomeDisabled;
+ set
+ {
+ PluginPair.Metadata.HomeDisabled = !value;
+ PluginSettingsObject.HomeDiabled = !value;
+ }
+ }
+
public bool IsExpanded
{
get => _isExpanded;
@@ -154,6 +164,7 @@ namespace Flow.Launcher.ViewModel
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 1179/1697] 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 b630a4ecc..34bf4f90e 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -159,7 +159,20 @@ namespace Flow.Launcher.Infrastructure.UserSettings
}
}
- 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 546f32cc5..6dcd8d22d 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -277,6 +277,17 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
.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 d850e0f7c..993cc3ba9 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1080,12 +1080,9 @@ namespace Flow.Launcher.ViewModel
#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 092896019..61f6dea33 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -82,6 +82,9 @@ namespace Flow.Launcher.ViewModel
{
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 1180/1697] 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 6dcd8d22d..e2948c540 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -278,12 +278,7 @@ namespace Flow.Launcher
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 61f6dea33..092896019 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -82,9 +82,6 @@ namespace Flow.Launcher.ViewModel
{
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 1181/1697] 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 993cc3ba9..8e708fbc4 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1127,9 +1127,20 @@ namespace Flow.Launcher.ViewModel
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 1182/1697] 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 caa3fd00b..c22651738 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -278,11 +278,8 @@ namespace Flow.Launcher.Core.Plugin
};
}
- 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 0ef3f30f5..fae821736 100644
--- a/Flow.Launcher.Core/Plugin/QueryBuilder.cs
+++ b/Flow.Launcher.Core/Plugin/QueryBuilder.cs
@@ -8,10 +8,23 @@ namespace Flow.Launcher.Core.Plugin
{
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 @@ namespace Flow.Launcher.Core.Plugin
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 8e708fbc4..517cf5323 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1220,31 +1220,21 @@ namespace Flow.Launcher.ViewModel
_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 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
{
if (string.IsNullOrWhiteSpace(queryText))
{
- return null;
+ return QueryBuilder.Build(string.Empty, PluginManager.NonGlobalPlugins);
}
var queryBuilder = new StringBuilder(queryText);
From 4ed1dc3bc12dc8eef98cc111e1013295715859e3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 4 May 2025 10:28:20 +0800
Subject: [PATCH 1183/1697] 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 c22651738..a3e80a73f 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -327,7 +327,7 @@ namespace Flow.Launcher.Core.Plugin
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 @@ namespace Flow.Launcher.Core.Plugin
token.ThrowIfCancellationRequested();
if (results == null)
return null;
- UpdatePluginMetadata(results, metadata);
+ UpdatePluginMetadata(results, metadata, query);
token.ThrowIfCancellationRequested();
}
@@ -372,16 +372,6 @@ namespace Flow.Launcher.Core.Plugin
}
}
- 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 517cf5323..eb22dc3e2 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1373,7 +1373,7 @@ namespace Flow.Launcher.ViewModel
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 1184/1697] 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 eb22dc3e2..64284d766 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1413,10 +1413,10 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
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 1185/1697] 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 837d0ebb6..920abc284 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/PluginSettings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/PluginSettings.cs
@@ -67,7 +67,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
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 @@ namespace Flow.Launcher.Infrastructure.UserSettings
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 @@ namespace Flow.Launcher.Infrastructure.UserSettings
/// 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 092896019..01fa3d203 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -81,7 +81,7 @@ namespace Flow.Launcher.ViewModel
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 1186/1697] 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 f3c9cfcad..129f43b85 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 1187/1697] 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 129f43b85..81186fca2 100644
--- a/Flow.Launcher.Plugin/Interfaces/IHomeQuery.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IHomeQuery.cs
@@ -17,7 +17,7 @@ namespace Flow.Launcher.Plugin
/// 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 1188/1697] 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 060c03317..f0fcd48ff 100644
--- a/Flow.Launcher.Plugin/Result.cs
+++ b/Flow.Launcher.Plugin/Result.cs
@@ -174,9 +174,6 @@ namespace Flow.Launcher.Plugin
///
/// 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 1189/1697] 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 6d7b4a8a4..f79596c96 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1192,8 +1192,27 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
};
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 @@ namespace Flow.Launcher.ViewModel
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 1190/1697] 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 f79596c96..5fd8d395f 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1346,7 +1346,7 @@ namespace Flow.Launcher.ViewModel
// 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 @@ namespace Flow.Launcher.ViewModel
}
}
- 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 @@ namespace Flow.Launcher.ViewModel
{
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 1191/1697] 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 fae821736..82745c239 100644
--- a/Flow.Launcher.Core/Plugin/QueryBuilder.cs
+++ b/Flow.Launcher.Core/Plugin/QueryBuilder.cs
@@ -16,7 +16,8 @@ namespace Flow.Launcher.Core.Plugin
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 c3eede4c6..7d98a4afe 100644
--- a/Flow.Launcher.Plugin/Query.cs
+++ b/Flow.Launcher.Plugin/Query.cs
@@ -53,6 +53,7 @@ namespace Flow.Launcher.Plugin
///
/// 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 1192/1697] 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 82745c239..fae821736 100644
--- a/Flow.Launcher.Core/Plugin/QueryBuilder.cs
+++ b/Flow.Launcher.Core/Plugin/QueryBuilder.cs
@@ -16,8 +16,7 @@ namespace Flow.Launcher.Core.Plugin
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 7d98a4afe..c3eede4c6 100644
--- a/Flow.Launcher.Plugin/Query.cs
+++ b/Flow.Launcher.Plugin/Query.cs
@@ -53,7 +53,6 @@ namespace Flow.Launcher.Plugin
///
/// 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 5fd8d395f..30df8250c 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -33,6 +33,7 @@ namespace Flow.Launcher.ViewModel
private bool _isQueryRunning;
private Query _lastQuery;
+ private bool _lastHomeQuery;
private string _queryTextBeforeLeaveResults;
private string _ignoredQueryText = null;
@@ -1261,6 +1262,8 @@ namespace Flow.Launcher.ViewModel
return;
}
+ var homeQuery = query.RawQuery == string.Empty;
+
_updateSource = new CancellationTokenSource();
ProgressBarVisibility = Visibility.Hidden;
@@ -1275,11 +1278,11 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
}
}
- 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 1193/1697] 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 c505c32a3..c481be02e 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1215,10 +1215,14 @@ namespace Flow.Launcher.ViewModel
{
_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 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
// 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 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
{
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 1194/1697] 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 c481be02e..228e66edb 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1215,7 +1215,7 @@ namespace Flow.Launcher.ViewModel
{
_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 1195/1697] 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 566cb6814..476c10e74 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -33,7 +33,7 @@ namespace Flow.Launcher.ViewModel
private bool _isQueryRunning;
private Query _lastQuery;
- private bool _lastHomeQuery;
+ private bool _lastIsHomeQuery;
private string _queryTextBeforeLeaveResults;
private string _ignoredQueryText = null;
@@ -1268,7 +1268,7 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
// 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 @@ namespace Flow.Launcher.ViewModel
{
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 @@ namespace Flow.Launcher.ViewModel
// 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 @@ namespace Flow.Launcher.ViewModel
}
}
- 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 1196/1697] 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 476c10e74..23958ca70 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -54,8 +54,8 @@ namespace Flow.Launcher.ViewModel
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 1197/1697] 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 23958ca70..dc35a6aa9 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -54,7 +54,7 @@ namespace Flow.Launcher.ViewModel
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 1198/1697] 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 dc35a6aa9..25c39ac7a 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1547,13 +1547,13 @@ namespace Flow.Launcher.ViewModel
// 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 1199/1697] 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 25c39ac7a..a8e431d99 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1544,8 +1544,13 @@ namespace Flow.Launcher.ViewModel
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 1200/1697] 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 a8e431d99..a98172f0a 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1221,19 +1221,15 @@ namespace Flow.Launcher.ViewModel
{
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 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
{
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 @@ namespace Flow.Launcher.ViewModel
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 1201/1697] 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 a98172f0a..6c4236db9 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -790,8 +790,6 @@ namespace Flow.Launcher.ViewModel
}
}
}
-
- _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 1202/1697] 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 6c4236db9..8ec29c216 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -35,7 +35,7 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
_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 1203/1697] 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 8ec29c216..175f4ff84 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -46,6 +46,7 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
_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 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
// 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 @@ namespace Flow.Launcher.ViewModel
{
// 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 @@ namespace Flow.Launcher.ViewModel
ProgressBarVisibility = Visibility.Visible;
}
},
- _updateSource.Token,
+ _updateToken,
TaskContinuationOptions.NotOnCanceled,
TaskScheduler.Default);
@@ -1346,7 +1350,7 @@ namespace Flow.Launcher.ViewModel
{
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 @@ namespace Flow.Launcher.ViewModel
{
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 @@ namespace Flow.Launcher.ViewModel
// 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 @@ namespace Flow.Launcher.ViewModel
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 1204/1697] 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 175f4ff84..afef8f64e 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -47,6 +47,7 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
_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 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
{
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 1205/1697] 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 afef8f64e..175f4ff84 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -47,7 +47,6 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
_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 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
{
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 1206/1697] 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 175f4ff84..383256dcc 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1268,9 +1268,9 @@ namespace Flow.Launcher.ViewModel
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 1207/1697] 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 383256dcc..175f4ff84 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1268,9 +1268,9 @@ namespace Flow.Launcher.ViewModel
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 1208/1697] 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 175f4ff84..aab2e2d03 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -69,8 +69,6 @@ namespace Flow.Launcher.ViewModel
_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 1209/1697] 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 aab2e2d03..c0b74dc68 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1266,9 +1266,12 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
// 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 @@ namespace Flow.Launcher.ViewModel
{
// 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 @@ namespace Flow.Launcher.ViewModel
ProgressBarVisibility = Visibility.Visible;
}
},
- _updateToken,
+ currentCancellationToken,
TaskContinuationOptions.NotOnCanceled,
TaskScheduler.Default);
@@ -1348,21 +1351,21 @@ namespace Flow.Launcher.ViewModel
{
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 @@ namespace Flow.Launcher.ViewModel
// 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 @@ namespace Flow.Launcher.ViewModel
}
}
- 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 1210/1697] 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 402812a92..942e94470 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -203,7 +203,7 @@ namespace Flow.Launcher
// 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 e2948c540..e243549e3 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -166,9 +166,6 @@ namespace Flow.Launcher
// 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 1211/1697] 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 c0b74dc68..0c299875f 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -33,7 +33,7 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
// 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 @@ namespace Flow.Launcher.ViewModel
// 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 @@ namespace Flow.Launcher.ViewModel
{
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 @@ namespace Flow.Launcher.ViewModel
// 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 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
}
}
- 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)
+
+ // 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();
- }
- // 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();
+ 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 bc0be0de8..1563f85ba 100644
--- a/Flow.Launcher/ViewModel/ResultsForUpdate.cs
+++ b/Flow.Launcher/ViewModel/ResultsForUpdate.cs
@@ -9,7 +9,8 @@ namespace Flow.Launcher.ViewModel
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 02fb379fa..cd2736afa 100644
--- a/Flow.Launcher/ViewModel/ResultsViewModel.cs
+++ b/Flow.Launcher/ViewModel/ResultsViewModel.cs
@@ -232,10 +232,15 @@ namespace Flow.Launcher.ViewModel
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 1212/1697] 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 633af7b6b..eabd118fb 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs
@@ -140,6 +140,29 @@ namespace Flow.Launcher.Plugin.Explorer
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 f7d5bdb18..79f8a5848 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 e4056131d..1c5d074a0 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Main.cs
@@ -8,7 +8,6 @@ using System.Collections.Generic;
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 1213/1697] 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 37de80451..700dc3a91 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 1214/1697] 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 7aaa9296a..003022ac5 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 1215/1697] 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 003022ac5..47bd66107 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 1216/1697] 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 0c299875f..df4144510 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -518,9 +518,10 @@ namespace Flow.Launcher.ViewModel
[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 1217/1697] 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 df4144510..52581ea1d 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -520,7 +520,7 @@ namespace Flow.Launcher.ViewModel
{
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 1218/1697] 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 7f35904a5..327ad8336 100644
--- a/Flow.Launcher/Storage/TopMostRecord.cs
+++ b/Flow.Launcher/Storage/TopMostRecord.cs
@@ -12,9 +12,7 @@ namespace Flow.Launcher.Storage
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 @@ namespace Flow.Launcher.Storage
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 0c299875f..efa6dd39d 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -444,12 +444,7 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
{
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 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
{
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 1219/1697] 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 327ad8336..7714b5001 100644
--- a/Flow.Launcher/Storage/TopMostRecord.cs
+++ b/Flow.Launcher/Storage/TopMostRecord.cs
@@ -12,8 +12,7 @@ namespace Flow.Launcher.Storage
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 1220/1697] 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 b5eafaae9..b81c5c9b5 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 806e9f203..71c9c8c6b 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 6055a79e1..37723dc9b 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 4fb441d8c..895a2dab6 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 23d58eca3..902811a56 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 8b3c42fa6..0dc6833af 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 e46e0dc9d..41fdbaa51 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 38e943cda..52eaf5e9f 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 fd34bf366..1a356ad65 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 e6f2223cd..949fe5c99 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 3aee3f5e4..9ae2e0195 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 b78bcb7d7..58571a1c4 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 ce3406142..70a58e322 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 12af37c3e..7cc6dfcb1 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.
- 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
+ Ustawienie opóźnienia wyszukiwania
+ Podaj czas opóźnienia wyszukiwania (w ms) dla wtyczki. Pozostaw puste, aby użyć wartości domyślnej.
+
+
+ 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 d0040d799..bd74d1d5f 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 9dc520cbd..cf7312956 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 c38855474..69069c5ec 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 0f07387c6..88ed1c9df 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 1d1eb9120..4b3e3bc0c 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 b9b5d351e..665694ace 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 427511c66..b3dc2cd16 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 6223efc00..b7b56213b 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 3d302da5b..bd3142992 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 cecad8e0d..1a71ae135 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 d278faf98..e553a1b7e 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 93916ffaa..a374e7fc1 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 4344e8c3d..06af5ea5b 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 15598118c..757394b4c 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 c61f8b3df..b751f3f39 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 df6199976..29c97a651 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 27f98449f..39d056e28 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 cc78c9a9a..7af9e9306 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 04619239d..006dd93d6 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 d621b63c4..d53616cc0 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 8563f49a0..0a7176d2c 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 766d170a4..7968ef2d8 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 9b4a20a69..50799dca2 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 ab788075e..6ab3f9797 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 7064de1fe..ae3b6bab2 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 8567b5412..15d14a42c 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 1333fe573..5bd4a9eac 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 8563f49a0..0a7176d2c 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 c3d1f6d08..09679a58b 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 1210818bf..37413385d 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 cfcd71c37..ea9f9a591 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 650f14657..7e59db5ec 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 8563f49a0..0a7176d2c 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 944a883c9..b50a31744 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 0e2bef052..d030a778e 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 2b06d3bbe..6c85b9476 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 8563f49a0..0a7176d2c 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 8563f49a0..0a7176d2c 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 02dab46ba..56004028b 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 89fd67635..5ce54a0dc 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 15e717c79..ceb909db1 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 8563f49a0..0a7176d2c 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 69ca16b69..d352368cb 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 1c70c6b6f..ca57bf027 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 0f39f5d56..a0f09a3b5 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 14e228b2a..ec5d273d6 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 b928bd1ce..d9ffa668c 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 57b5c94b7..d0b6851d9 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 7cccd5a42..e6fd67936 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 af272fb46..88053ac57 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 cf5de9bab..5004d41cf 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 1f1dd4d37..96ca3af60 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 affa7567f..266aa4b45 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 3fa53aba8..c4b218204 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 8a86dc511..495296694 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 8a163de7a..f38fd9623 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 bab077683..3ff8be551 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 c7b394593..aa3c500a3 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 8cb62137e..a75a6d836 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 ee0705b96..7fda65160 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 a69d7e96b..f2da895b0 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 d46de0592..6bda659dd 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 8e8d55f47..3686925a9 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 21a3981c5..6b238c638 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 6d5c0079f..b36b72b9b 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 fd0bd427a..084adfbac 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 90eb49317..781227267 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 86688a130..b02a89a0a 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 bc7dff59f..27fee87be 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 f2049038f..e38e6e68b 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 9ae628853..4112f41ff 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 3ac9f6a6c..c8f069ca7 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 faa8c2dcc..5bf27c746 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 1221/1697] 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 e243549e3..46eeb2adc 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -22,6 +22,7 @@ using Flow.Launcher.Infrastructure.Image;
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 @@ namespace Flow.Launcher
InitSoundEffects();
DataObject.AddPastingHandler(QueryTextBox, QueryTextBox_OnPaste);
+
+ SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
}
#endregion
@@ -540,16 +543,29 @@ namespace Flow.Launcher
#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 @@ namespace Flow.Launcher
{
Name = progressBarAnimationName, Storyboard = progressBarStoryBoard
};
-
+
var stopStoryboard = new StopStoryboard()
{
BeginStoryboardName = progressBarAnimationName
@@ -837,7 +853,7 @@ namespace Flow.Launcher
progressStyle.Triggers.Add(trigger);
ProgressBar.Style = progressStyle;
-
+
_viewModel.ProgressBarVisibility = Visibility.Hidden;
}
@@ -885,7 +901,7 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
{
e.Handled = true;
}
-
+
#endregion
#region Placeholder
@@ -1140,7 +1156,7 @@ namespace Flow.Launcher
}
#endregion
-
+
#region Search Delay
private void QueryTextBox_TextChanged1(object sender, TextChangedEventArgs e)
@@ -1162,6 +1178,9 @@ namespace Flow.Launcher
{
_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 1222/1697] 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 66be08903..e859976bd 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
@@ -131,7 +131,17 @@ public abstract class ChromiumBookmarkLoader : IBookmarkLoader
}
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 1223/1697] 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 9ad31ad14..155069495 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs
@@ -37,8 +37,6 @@ public class Main : ISettingProvider, IPlugin, IReloadable, IPluginI18n, IContex
context.CurrentPluginMetadata.PluginCacheDirectoryPath,
"FaviconCache");
- FilesFolders.ValidateDirectory(_faviconCacheDir);
-
LoadBookmarksIfEnabled();
}
@@ -50,6 +48,9 @@ public class Main : ISettingProvider, IPlugin, IReloadable, IPluginI18n, IContex
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 1224/1697] 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 a3e80a73f..eb775c2f0 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -220,9 +220,17 @@ namespace Flow.Launcher.Core.Plugin
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 1225/1697] 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 34bf4f90e..ce1269a29 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -293,6 +293,10 @@ namespace Flow.Launcher.Infrastructure.UserSettings
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 46eeb2adc..230472d88 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -711,8 +711,26 @@ namespace Flow.Launcher
{
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 @@ namespace Flow.Launcher
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 @@ namespace Flow.Launcher
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 79bd171ed..cf84317ac 100644
--- a/Flow.Launcher/SettingWindow.xaml.cs
+++ b/Flow.Launcher/SettingWindow.xaml.cs
@@ -137,18 +137,40 @@ public partial class SettingWindow
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 1226/1697] 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 eb775c2f0..c9d13b61d 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -219,17 +219,18 @@ namespace Flow.Launcher.Core.Plugin
}
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 1227/1697] 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 c9d13b61d..690fda011 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -219,6 +219,7 @@ namespace Flow.Launcher.Core.Plugin
}
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 @@ namespace Flow.Launcher.Core.Plugin
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 1228/1697] 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 d542eb019..f1f3e22c6 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
@@ -479,7 +479,7 @@ public partial class SettingsPaneThemeViewModel : BaseModel
)
}
};
- 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 401f71ae3..ac339b715 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -148,19 +148,19 @@ namespace Flow.Launcher.ViewModel
_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 @@ namespace Flow.Launcher.ViewModel
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 cd2736afa..799546808 100644
--- a/Flow.Launcher/ViewModel/ResultsViewModel.cs
+++ b/Flow.Launcher/ViewModel/ResultsViewModel.cs
@@ -21,6 +21,7 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
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 @@ namespace Flow.Launcher.ViewModel
UpdateResults(newResults);
}
+
///
/// To avoid deadlock, this method should not called from main thread
///
@@ -202,11 +205,18 @@ namespace Flow.Launcher.ViewModel
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 1229/1697] 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 799546808..b91bf0f30 100644
--- a/Flow.Launcher/ViewModel/ResultsViewModel.cs
+++ b/Flow.Launcher/ViewModel/ResultsViewModel.cs
@@ -211,8 +211,8 @@ namespace Flow.Launcher.ViewModel
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 1230/1697] 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 f1f3e22c6..07d70a67c 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
@@ -479,6 +479,7 @@ public partial class SettingsPaneThemeViewModel : BaseModel
)
}
};
+ // 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 b91bf0f30..0dc1b85c4 100644
--- a/Flow.Launcher/ViewModel/ResultsViewModel.cs
+++ b/Flow.Launcher/ViewModel/ResultsViewModel.cs
@@ -211,7 +211,7 @@ namespace Flow.Launcher.ViewModel
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 1231/1697] 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 0dc1b85c4..b100bba25 100644
--- a/Flow.Launcher/ViewModel/ResultsViewModel.cs
+++ b/Flow.Launcher/ViewModel/ResultsViewModel.cs
@@ -211,7 +211,7 @@ namespace Flow.Launcher.ViewModel
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 1232/1697] 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 690fda011..aae8dd764 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -224,7 +224,7 @@ namespace Flow.Launcher.Core.Plugin
{
// 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 1233/1697] 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 07d70a67c..79465cd71 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
@@ -479,7 +479,7 @@ public partial class SettingsPaneThemeViewModel : BaseModel
)
}
};
- // 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 1234/1697] 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 ee6b4379d..c19347f2a 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 5c0ba8d0b..3bf1c6ad1 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 @@ namespace Flow.Launcher.Plugin.Program.Views
{
btnProgramSourceStatus.Visibility = Visibility.Visible;
btnEditProgramSource.Visibility = Visibility.Visible;
+ btnDeleteProgramSource.Visibility = Visibility.Visible;
}
programSourceView.Items.Refresh();
@@ -270,8 +272,8 @@ namespace Flow.Launcher.Plugin.Program.Views
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 @@ namespace Flow.Launcher.Plugin.Program.Views
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 @@ namespace Flow.Launcher.Plugin.Program.Views
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 @@ namespace Flow.Launcher.Plugin.Program.Views
.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 @@ namespace Flow.Launcher.Plugin.Program.Views
}
}
+ [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 @@ namespace Flow.Launcher.Plugin.Program.Views
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 1235/1697] 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 c19347f2a..bf6de50fe 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 71879181e..59ee40c12 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 @@ namespace Flow.Launcher.Plugin.Program.Views
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 1236/1697] 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 bf6de50fe..65fd8951c 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 59ee40c12..8b19ba81c 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 @@ namespace Flow.Launcher.Plugin.Program.Views
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 1237/1697] 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 65fd8951c..e551a7dcb 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 8b19ba81c..6ae1c4422 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 @@ namespace Flow.Launcher.Plugin.Program.Views
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 @@ namespace Flow.Launcher.Plugin.Program.Views
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 1238/1697] 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 811bec50c..f23ff71f0 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Settings.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Settings.cs
@@ -10,6 +10,6 @@
public bool WarnFromUnknownSource { get; set; } = true;
- public bool AutoRestartAfterChanging { get; set; } = true;
+ public bool AutoRestartAfterChanging { get; set; } = false;
}
}
From 8aa36f38c82a388c386d7e3d86c44798dad632ad Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 13 May 2025 21:50:13 +0800
Subject: [PATCH 1239/1697] Add ShowAtTopmost in settings
---
.../UserSettings/Settings.cs | 38 +++++++++++++++----
1 file changed, 30 insertions(+), 8 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index 34bf4f90e..3f382c276 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -59,8 +59,11 @@ namespace Flow.Launcher.Infrastructure.UserSettings
get => _language;
set
{
- _language = value;
- OnPropertyChanged();
+ if (_language != value)
+ {
+ _language = value;
+ OnPropertyChanged();
+ }
}
}
public string Theme
@@ -68,7 +71,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
get => _theme;
set
{
- if (value != _theme)
+ if (_theme != value)
{
_theme = value;
OnPropertyChanged();
@@ -283,9 +286,12 @@ namespace Flow.Launcher.Infrastructure.UserSettings
get => _querySearchPrecision;
set
{
- _querySearchPrecision = value;
- if (_stringMatcher != null)
- _stringMatcher.UserSettingSearchPrecision = value;
+ if (_querySearchPrecision != value)
+ {
+ _querySearchPrecision = value;
+ if (_stringMatcher != null)
+ _stringMatcher.UserSettingSearchPrecision = value;
+ }
}
}
@@ -348,12 +354,28 @@ namespace Flow.Launcher.Infrastructure.UserSettings
get => _hideNotifyIcon;
set
{
- _hideNotifyIcon = value;
- OnPropertyChanged();
+ if (_hideNotifyIcon != value)
+ {
+ _hideNotifyIcon = value;
+ OnPropertyChanged();
+ }
}
}
public bool LeaveCmdOpen { get; set; }
public bool HideWhenDeactivated { get; set; } = true;
+ private bool _showAtTopmost;
+ public bool ShowAtTopmost
+ {
+ get => _showAtTopmost;
+ set
+ {
+ if (_showAtTopmost != value)
+ {
+ _showAtTopmost = value;
+ OnPropertyChanged();
+ }
+ }
+ }
public bool SearchQueryResultsWithDelay { get; set; }
public int SearchDelayTime { get; set; } = 150;
From 587ab629aa9b831ba8ed684eb2039dbba6b28ff1 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 13 May 2025 21:54:03 +0800
Subject: [PATCH 1240/1697] Support changing ShowAtTopmost
---
Flow.Launcher/MainWindow.xaml.cs | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 46eeb2adc..72a990ada 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -84,6 +84,8 @@ namespace Flow.Launcher
_viewModel = Ioc.Default.GetRequiredService();
DataContext = _viewModel;
+ Topmost = _settings.ShowAtTopmost;
+
InitializeComponent();
UpdatePosition();
@@ -283,6 +285,9 @@ namespace Flow.Launcher
_viewModel.QueryResults();
}
break;
+ case nameof(Settings.ShowAtTopmost):
+ Topmost = _settings.ShowAtTopmost;
+ break;
}
};
From 4e88ce3f48b9eae47dc57c595acfe7862b540476 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 13 May 2025 22:01:36 +0800
Subject: [PATCH 1241/1697] Set ShowAtTopmost default to true
---
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 3f382c276..7cd3821dc 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -363,7 +363,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
}
public bool LeaveCmdOpen { get; set; }
public bool HideWhenDeactivated { get; set; } = true;
- private bool _showAtTopmost;
+ private bool _showAtTopmost = true;
public bool ShowAtTopmost
{
get => _showAtTopmost;
From b8f743eb4c2ad44bc89366698a6ee8543d1d5343 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 13 May 2025 22:06:04 +0800
Subject: [PATCH 1242/1697] Add ui in general setting page
---
Flow.Launcher/Languages/en.xaml | 2 ++
.../SettingPages/Views/SettingsPaneGeneral.xaml | 11 +++++++++++
2 files changed, 13 insertions(+)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 22ab2016c..f728f1095 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -131,6 +131,8 @@
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.
+ Show Search Window at Topmost
+ Show search window above other windows
Search Plugin
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
index c0c5613de..fba1b3d86 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
@@ -77,6 +77,17 @@
OnContent="{DynamicResource enable}" />
+
+
+
+
From b636f253e65114639dca2aa7d14271d013a993a6 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 13 May 2025 22:52:06 +0800
Subject: [PATCH 1243/1697] Add blank line
---
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 7cd3821dc..8dc48f7f2 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -363,6 +363,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
}
public bool LeaveCmdOpen { get; set; }
public bool HideWhenDeactivated { get; set; } = true;
+
private bool _showAtTopmost = true;
public bool ShowAtTopmost
{
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 1244/1697] 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 6ae1c4422..9ac447085 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 @@ namespace Flow.Launcher.Plugin.Program.Views
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 @@ namespace Flow.Launcher.Plugin.Program.Views
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 @@ namespace Flow.Launcher.Plugin.Program.Views
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 1245/1697] 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 46eeb2adc..0b7ebf148 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -89,7 +89,7 @@ namespace Flow.Launcher
InitSoundEffects();
DataObject.AddPastingHandler(QueryTextBox, QueryTextBox_OnPaste);
-
+ ModernWpf.ThemeManager.Current.ActualApplicationThemeChanged += ThemeManager_ActualApplicationThemeChanged;
SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
}
@@ -543,6 +543,10 @@ namespace Flow.Launcher
#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 1246/1697] 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 0b7ebf148..ab26d417c 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -1184,6 +1184,7 @@ namespace Flow.Launcher
_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 1247/1697] 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 0b7ebf148..4465c8e33 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -99,6 +99,11 @@ namespace Flow.Launcher
#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 @@ namespace Flow.Launcher
#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 @@ namespace Flow.Launcher
_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 1248/1697] 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 deb110698..57c1542e4 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 @@ namespace Flow.Launcher.Plugin.Program.Views
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 0a38fda04..1a8621eeb 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/SysSettings.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/SysSettings.xaml.cs
@@ -21,16 +21,15 @@ namespace Flow.Launcher.Plugin.Sys
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 1249/1697] 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 a75a51c8f..da128266c 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 1250/1697] 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 a3b008206..1b1dd21e9 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs
@@ -14,7 +14,7 @@ namespace Flow.Launcher.Resources.Pages
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 a63edbcda..7408d8a14 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs
@@ -16,7 +16,7 @@ namespace Flow.Launcher.Resources.Pages
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 4a6610e61..bd14bf0f7 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage3.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage3.xaml.cs
@@ -12,7 +12,7 @@ namespace Flow.Launcher.Resources.Pages
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 1ee3284d2..b20e4ce0a 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage4.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage4.xaml.cs
@@ -12,7 +12,7 @@ namespace Flow.Launcher.Resources.Pages
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 6328c9914..84d298966 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage5.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage5.xaml.cs
@@ -15,7 +15,7 @@ namespace Flow.Launcher.Resources.Pages
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 e57cba6d4..93515caec 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 31653962d..fa3406bd9 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 8b757bd60..e590dc9a8 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 5ddfe4650..aa6900dae 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 e9490804a..6424aabdf 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 258f2a4ad..c89a050f5 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 cee8e4ae4..8759c8efc 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 cf84317ac..14e4343e3 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 @@ public partial class SettingWindow
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 17a1a2b50..9e7eaf6e8 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 partial class SettingWindowViewModel : BaseModel
_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 1251/1697] 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 1b1dd21e9..3199e81b7 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs
@@ -14,10 +14,14 @@ namespace Flow.Launcher.Resources.Pages
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 7408d8a14..1eef9fc8c 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs
@@ -16,10 +16,14 @@ namespace Flow.Launcher.Resources.Pages
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 bd14bf0f7..d27368aa1 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage3.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage3.xaml.cs
@@ -12,10 +12,14 @@ namespace Flow.Launcher.Resources.Pages
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 b20e4ce0a..b0999504b 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage4.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage4.xaml.cs
@@ -12,10 +12,14 @@ namespace Flow.Launcher.Resources.Pages
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 84d298966..2ece4ce88 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage5.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage5.xaml.cs
@@ -15,10 +15,14 @@ namespace Flow.Launcher.Resources.Pages
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 93515caec..00426546a 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 fa3406bd9..524e4f5f5 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 e590dc9a8..53a639aa5 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 aa6900dae..34cd33ec1 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 6424aabdf..94e0d24a2 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 c89a050f5..aa47383e8 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 8759c8efc..215a8c70c 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 1252/1697] 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 14e4343e3..d8444d45d 100644
--- a/Flow.Launcher/SettingWindow.xaml.cs
+++ b/Flow.Launcher/SettingWindow.xaml.cs
@@ -263,6 +263,7 @@ public partial class SettingWindow
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 9e7eaf6e8..5b130eb6d 100644
--- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
+++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
@@ -14,6 +14,11 @@ public partial class SettingWindowViewModel : BaseModel
_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 1253/1697] 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 00426546a..47532b243 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 524e4f5f5..753cb7b0e 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 53a639aa5..202869bc5 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 34cd33ec1..c0a77957a 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 @@ public partial class SettingsPanePluginStore
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 94e0d24a2..f486a3443 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 @@ public partial class SettingsPanePlugins
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 aa47383e8..3e617229d 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 215a8c70c..170003994 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 d8444d45d..ebbb38414 100644
--- a/Flow.Launcher/SettingWindow.xaml.cs
+++ b/Flow.Launcher/SettingWindow.xaml.cs
@@ -241,6 +241,7 @@ public partial class SettingWindow
{
if (args.IsSettingsSelected)
{
+ _viewModel.SetPageType(typeof(SettingsPaneGeneral));
ContentFrame.Navigate(typeof(SettingsPaneGeneral));
}
else
@@ -263,8 +264,11 @@ public partial class SettingWindow
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 @@ public partial class SettingWindow
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 5b130eb6d..1134a81b8 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 partial class SettingWindowViewModel : BaseModel
_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 1254/1697] 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 3199e81b7..16252086e 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 1eef9fc8c..37767f128 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 d27368aa1..4c3184f8c 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();
- }
+ // Sometimes the navigation is not triggered by button click,
+ // so we need to reset the page number
+ _viewModel.PageNum = 3;
+
if (!IsInitialized)
{
InitializeComponent();
}
- // Sometimes the navigation is not triggered by button click,
- // so we need to reset the page number
- _viewModel.PageNum = 3;
base.OnNavigatedTo(e);
}
}
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage4.xaml.cs b/Flow.Launcher/Resources/Pages/WelcomePage4.xaml.cs
index b0999504b..63c9b9a7a 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage4.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage4.xaml.cs
@@ -7,24 +7,19 @@ namespace Flow.Launcher.Resources.Pages
{
public partial class WelcomePage4
{
- 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 = 4;
+
if (!IsInitialized)
{
InitializeComponent();
}
- // Sometimes the navigation is not triggered by button click,
- // so we need to reset the page number
- _viewModel.PageNum = 4;
base.OnNavigatedTo(e);
}
}
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage5.xaml.cs b/Flow.Launcher/Resources/Pages/WelcomePage5.xaml.cs
index 2ece4ce88..8db0a9f7e 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage5.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage5.xaml.cs
@@ -10,24 +10,19 @@ namespace Flow.Launcher.Resources.Pages
{
public partial class WelcomePage5
{
- 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 = 5;
+
if (!IsInitialized)
{
InitializeComponent();
}
- // Sometimes the navigation is not triggered by button click,
- // so we need to reset the page number
- _viewModel.PageNum = 5;
base.OnNavigatedTo(e);
}
From 7e3de02ecb020468532b577e16eba0db466b1df0 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 16 May 2025 19:23:49 +0800
Subject: [PATCH 1255/1697] initialize position before InitializeComponent
---
Flow.Launcher/SettingWindow.xaml.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/SettingWindow.xaml.cs b/Flow.Launcher/SettingWindow.xaml.cs
index ebbb38414..ed4f4eb08 100644
--- a/Flow.Launcher/SettingWindow.xaml.cs
+++ b/Flow.Launcher/SettingWindow.xaml.cs
@@ -30,9 +30,9 @@ public partial class SettingWindow
_settings = Ioc.Default.GetRequiredService();
_viewModel = Ioc.Default.GetRequiredService();
DataContext = _viewModel;
- InitializeComponent();
-
+ // Because WindowStartupLocation is Manual, so we need to initialize position before InitializeComponent
UpdatePositionAndState();
+ InitializeComponent();
}
#endregion
From 07ac325593718ec9fee3a57aadcc6fabd07a8c2e Mon Sep 17 00:00:00 2001
From: Jack Ye <1160210343@qq.com>
Date: Fri, 16 May 2025 19:27:10 +0800
Subject: [PATCH 1256/1697] Improve code comments
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
Flow.Launcher/SettingWindow.xaml.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/SettingWindow.xaml.cs b/Flow.Launcher/SettingWindow.xaml.cs
index ed4f4eb08..c53a4ea80 100644
--- a/Flow.Launcher/SettingWindow.xaml.cs
+++ b/Flow.Launcher/SettingWindow.xaml.cs
@@ -30,7 +30,7 @@ public partial class SettingWindow
_settings = Ioc.Default.GetRequiredService();
_viewModel = Ioc.Default.GetRequiredService();
DataContext = _viewModel;
- // Because WindowStartupLocation is Manual, so we need to initialize position before InitializeComponent
+ // Since WindowStartupLocation is set to Manual, initialize the window position before calling InitializeComponent
UpdatePositionAndState();
InitializeComponent();
}
From 050c2cb64781a4eba0cb84474dfde815d65c5d30 Mon Sep 17 00:00:00 2001
From: DB p
Date: Sat, 17 May 2025 15:08:20 +0900
Subject: [PATCH 1257/1697] Refactor OpenDirectory method to improve path
handling and streamline process start logic
---
Flow.Launcher/PublicAPIInstance.cs | 48 ++++++++++++++++++++++--------
1 file changed, 36 insertions(+), 12 deletions(-)
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 5b8e8c9af..28b4b0429 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -314,24 +314,48 @@ namespace Flow.Launcher
((PluginJsonStorage)_pluginJsonStorages[type]).Save();
}
- public void OpenDirectory(string DirectoryPath, string FileNameOrFilePath = null)
+ public void OpenDirectory(string directoryPath, string fileNameOrFilePath = null)
{
- using var explorer = new Process();
- var explorerInfo = _settings.CustomExplorer;
+ string targetPath;
- explorer.StartInfo = new ProcessStartInfo
+ if (fileNameOrFilePath is null)
{
- FileName = explorerInfo.Path.Replace("%d", DirectoryPath),
+ targetPath = directoryPath;
+ }
+ else
+ {
+ targetPath = Path.IsPathRooted(fileNameOrFilePath)
+ ? fileNameOrFilePath
+ : Path.Combine(directoryPath, fileNameOrFilePath);
+ }
+
+ var explorerInfo = _settings.CustomExplorer;
+ var explorerPath = explorerInfo.Path.Trim().ToLowerInvariant();
+
+ // If explorer.exe, ignore and pass only the path to Shell
+ if (Path.GetFileNameWithoutExtension(explorerPath) == "explorer")
+ {
+ Process.Start(new ProcessStartInfo
+ {
+ FileName = targetPath, // Not explorer, Only path.
+ UseShellExecute = true // Must be true to open folder
+ });
+ return;
+ }
+
+ // Custom File Manager
+ var psi = new ProcessStartInfo
+ {
+ FileName = explorerInfo.Path.Replace("%d", directoryPath),
UseShellExecute = true,
- Arguments = FileNameOrFilePath is null
- ? explorerInfo.DirectoryArgument.Replace("%d", DirectoryPath)
+ Arguments = fileNameOrFilePath is null
+ ? explorerInfo.DirectoryArgument.Replace("%d", directoryPath)
: explorerInfo.FileArgument
- .Replace("%d", DirectoryPath)
- .Replace("%f",
- Path.IsPathRooted(FileNameOrFilePath) ? FileNameOrFilePath : Path.Combine(DirectoryPath, FileNameOrFilePath)
- )
+ .Replace("%d", directoryPath)
+ .Replace("%f", targetPath)
};
- explorer.Start();
+
+ Process.Start(psi);
}
private void OpenUri(Uri uri, bool? inPrivate = null)
From b5bbd9f123ede83f9fe53732a28bb17952c60b21 Mon Sep 17 00:00:00 2001
From: DB p
Date: Sat, 17 May 2025 15:16:34 +0900
Subject: [PATCH 1258/1697] Refactor OpenDirectory method to standardize
parameter naming and improve path handling
---
Flow.Launcher/PublicAPIInstance.cs | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 28b4b0429..ad48081b4 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -314,19 +314,19 @@ namespace Flow.Launcher
((PluginJsonStorage)_pluginJsonStorages[type]).Save();
}
- public void OpenDirectory(string directoryPath, string fileNameOrFilePath = null)
+ public void OpenDirectory(string DirectoryPath, string FileNameOrFilePath = null)
{
string targetPath;
- if (fileNameOrFilePath is null)
+ if (FileNameOrFilePath is null)
{
- targetPath = directoryPath;
+ targetPath = DirectoryPath;
}
else
{
- targetPath = Path.IsPathRooted(fileNameOrFilePath)
- ? fileNameOrFilePath
- : Path.Combine(directoryPath, fileNameOrFilePath);
+ targetPath = Path.IsPathRooted(FileNameOrFilePath)
+ ? FileNameOrFilePath
+ : Path.Combine(DirectoryPath, FileNameOrFilePath);
}
var explorerInfo = _settings.CustomExplorer;
@@ -346,12 +346,12 @@ namespace Flow.Launcher
// Custom File Manager
var psi = new ProcessStartInfo
{
- FileName = explorerInfo.Path.Replace("%d", directoryPath),
+ FileName = explorerInfo.Path.Replace("%d", DirectoryPath),
UseShellExecute = true,
- Arguments = fileNameOrFilePath is null
- ? explorerInfo.DirectoryArgument.Replace("%d", directoryPath)
+ Arguments = FileNameOrFilePath is null
+ ? explorerInfo.DirectoryArgument.Replace("%d", DirectoryPath)
: explorerInfo.FileArgument
- .Replace("%d", directoryPath)
+ .Replace("%d", DirectoryPath)
.Replace("%f", targetPath)
};
From 003df049e1c7f32313df55fccadab171b6833277 Mon Sep 17 00:00:00 2001
From: Jeremy
Date: Sat, 17 May 2025 20:40:40 +1000
Subject: [PATCH 1259/1697] add dedicated clear result indicator for query and
non-query usage
---
Flow.Launcher/ViewModel/MainViewModel.cs | 36 ++++++++++++++++++------
1 file changed, 27 insertions(+), 9 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 401f71ae3..64fb85296 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -267,7 +267,7 @@ namespace Flow.Launcher.ViewModel
if (token.IsCancellationRequested) return;
- if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(resultsCopy, pair.Metadata, e.Query,
+ if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(resultsCopy, pair.Metadata, e.Query,
token)))
{
App.API.LogError(ClassName, "Unable to add item to Result Update Queue");
@@ -793,7 +793,7 @@ namespace Flow.Launcher.ViewModel
public Visibility ProgressBarVisibility { get; set; }
public Visibility MainWindowVisibility { get; set; }
-
+
// This is to be used for determining the visibility status of the main window instead of MainWindowVisibility
// because it is more accurate and reliable representation than using Visibility as a condition check
public bool MainWindowVisibilityStatus { get; set; } = true;
@@ -1070,7 +1070,7 @@ namespace Flow.Launcher.ViewModel
path = QueryResultsPreviewed() ? Results.SelectedItem?.Result?.Preview.FilePath : string.Empty;
return !string.IsNullOrEmpty(path);
}
-
+
private bool QueryResultsPreviewed()
{
var previewed = PreviewSelectedItem == Results.SelectedItem;
@@ -1280,7 +1280,7 @@ namespace Flow.Launcher.ViewModel
// Update the query's IsReQuery property to true if this is a re-query
query.IsReQuery = isReQuery;
-
+
ICollection plugins = Array.Empty();
if (currentIsHomeQuery)
@@ -1312,8 +1312,7 @@ namespace Flow.Launcher.ViewModel
}
}
- var validPluginNames = plugins.Select(x => $"<{x.Metadata.Name}>");
- App.API.LogDebug(ClassName, $"Valid <{plugins.Count}> plugins: {string.Join(" ", validPluginNames)}");
+ App.API.LogDebug(ClassName, $"Valid <{plugins.Count}> plugins: {string.Join(" ", plugins.Select(x => $"<{x.Metadata.Name}>"))}");
// Do not wait for performance improvement
/*if (string.IsNullOrEmpty(query.ActionKeyword))
@@ -1341,6 +1340,9 @@ namespace Flow.Launcher.ViewModel
Task[] tasks;
if (currentIsHomeQuery)
{
+ if (ShouldClearExistingResultsForNonQuery(plugins))
+ Results.Clear();
+
tasks = plugins.Select(plugin => plugin.Metadata.HomeDisabled switch
{
false => QueryTaskAsync(plugin, currentCancellationToken),
@@ -1432,7 +1434,7 @@ namespace Flow.Launcher.ViewModel
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);
+ var shouldClearExistingResults = ShouldClearExistingResultsForQuery(query, currentIsHomeQuery);
_lastQuery = query;
_previousIsHomeQuery = currentIsHomeQuery;
@@ -1454,8 +1456,13 @@ namespace Flow.Launcher.ViewModel
App.API.LogDebug(ClassName, $"Update results for history");
+ // Indicate if to clear existing results so to show only ones from plugins with action keywords
+ var shouldClearExistingResults = ShouldClearExistingResultsForQuery(query, currentIsHomeQuery);
+ _lastQuery = query;
+ _previousIsHomeQuery = currentIsHomeQuery;
+
if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(results, _historyMetadata, query,
- token)))
+ token, reSelect, shouldClearExistingResults)))
{
App.API.LogError(ClassName, "Unable to add item to Result Update Queue");
}
@@ -1552,7 +1559,7 @@ namespace Flow.Launcher.ViewModel
/// 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)
+ private bool ShouldClearExistingResultsForQuery(Query query, bool currentIsHomeQuery)
{
// If previous or current results are from home query, we need to clear them
if (_previousIsHomeQuery || currentIsHomeQuery)
@@ -1571,6 +1578,17 @@ namespace Flow.Launcher.ViewModel
return false;
}
+ private bool ShouldClearExistingResultsForNonQuery(ICollection plugins)
+ {
+ if (!Settings.ShowHistoryResultsForHomePage && (plugins.Count == 0 || plugins.All(x => x.Metadata.HomeDisabled == true)))
+ {
+ App.API.LogDebug(ClassName, $"Cleared old results");
+ return true;
+ }
+
+ return false;
+ }
+
private Result ContextMenuTopMost(Result result)
{
Result menu;
From b4955f7474ac7b07658fb40220551865cb9d96aa Mon Sep 17 00:00:00 2001
From: Jeremy
Date: Sat, 17 May 2025 20:41:25 +1000
Subject: [PATCH 1260/1697] add subscriber for show history result toggle in
settings
---
.../UserSettings/Settings.cs | 15 ++++++++++++++-
Flow.Launcher/MainWindow.xaml.cs | 1 +
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index 34bf4f90e..387469d24 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -173,7 +173,20 @@ namespace Flow.Launcher.Infrastructure.UserSettings
}
}
- public bool ShowHistoryResultsForHomePage { get; set; } = false;
+ public bool _showHistoryResultsForHomePage { get; set; } = false;
+ public bool ShowHistoryResultsForHomePage
+ {
+ get => _showHistoryResultsForHomePage;
+ set
+ {
+ if(_showHistoryResultsForHomePage != value)
+ {
+ _showHistoryResultsForHomePage = value;
+ OnPropertyChanged();
+ }
+ }
+ }
+
public int MaxHistoryResultsToShowForHomePage { get; set; } = 5;
public int CustomExplorerIndex { get; set; } = 0;
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index e243549e3..18bceedd8 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -275,6 +275,7 @@ namespace Flow.Launcher
InitializeContextMenu();
break;
case nameof(Settings.ShowHomePage):
+ case nameof(Settings.ShowHistoryResultsForHomePage):
if (_viewModel.QueryResultsSelected() && string.IsNullOrEmpty(_viewModel.QueryText))
{
_viewModel.QueryResults();
From 2941e036bc864507211ed37ed9ba2ec140862daf Mon Sep 17 00:00:00 2001
From: Jeremy
Date: Sat, 17 May 2025 21:08:18 +1000
Subject: [PATCH 1261/1697] add logging and method summaries
---
Flow.Launcher/ViewModel/MainViewModel.cs | 23 +++++++++++++++++----
Flow.Launcher/ViewModel/ResultsViewModel.cs | 3 +++
2 files changed, 22 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 64fb85296..bfda18b9a 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1341,7 +1341,11 @@ namespace Flow.Launcher.ViewModel
if (currentIsHomeQuery)
{
if (ShouldClearExistingResultsForNonQuery(plugins))
+ {
Results.Clear();
+ App.API.LogDebug(ClassName, $"Existing results are cleared for non-query");
+ }
+
tasks = plugins.Select(plugin => plugin.Metadata.HomeDisabled switch
{
@@ -1548,7 +1552,9 @@ namespace Flow.Launcher.ViewModel
///
/// 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
+ /// This is used to indicate to QueryTaskAsync or QueryHistoryTask whether to clear results. If both QueryTaskAsync and QueryHistoryTask
+ /// are not called then use ShouldClearExistingResultsForNonQuery instead.
+ /// This method 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.
@@ -1564,25 +1570,34 @@ namespace Flow.Launcher.ViewModel
// If previous or current results are from home query, we need to clear them
if (_previousIsHomeQuery || currentIsHomeQuery)
{
- App.API.LogDebug(ClassName, $"Cleared old results");
+ App.API.LogDebug(ClassName, $"Existing results should be cleared for query");
return true;
}
// 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, $"Cleared old results");
+ App.API.LogDebug(ClassName, $"Existing results should be cleared for query");
return true;
}
return false;
}
+ ///
+ /// Determines whether existing results should be cleared for non-query calls.
+ /// A non-query call is where QueryTaskAsync and QueryHistoryTask methods are both not called.
+ /// QueryTaskAsync and QueryHistoryTask both handle result updating (clearing if required) so directly calling
+ /// Results.Clear() is not required. However when both are not called, we need to directly clear results and this
+ /// method determines on the condition when clear results should happen.
+ ///
+ /// The collection of plugins to check.
+ /// True if existing results should be cleared, false otherwise.
private bool ShouldClearExistingResultsForNonQuery(ICollection plugins)
{
if (!Settings.ShowHistoryResultsForHomePage && (plugins.Count == 0 || plugins.All(x => x.Metadata.HomeDisabled == true)))
{
- App.API.LogDebug(ClassName, $"Cleared old results");
+ App.API.LogDebug(ClassName, $"Existing results should be cleared for non-query");
return true;
}
diff --git a/Flow.Launcher/ViewModel/ResultsViewModel.cs b/Flow.Launcher/ViewModel/ResultsViewModel.cs
index cd2736afa..46a92f750 100644
--- a/Flow.Launcher/ViewModel/ResultsViewModel.cs
+++ b/Flow.Launcher/ViewModel/ResultsViewModel.cs
@@ -235,7 +235,10 @@ namespace Flow.Launcher.ViewModel
var newResults = resultsForUpdates.SelectMany(u => u.Results, (u, r) => new ResultViewModel(r, _settings));
if (resultsForUpdates.Any(x => x.shouldClearExistingResults))
+ {
+ App.API.LogDebug("NewResults", $"Existing results are cleared for query");
return newResults.OrderByDescending(rv => rv.Result.Score).ToList();
+ }
return Results.Where(r => r?.Result != null && resultsForUpdates.All(u => u.ID != r.Result.PluginID))
.Concat(newResults)
From 50fced959e768c333895af98e8323d6f1e67595a Mon Sep 17 00:00:00 2001
From: Jeremy
Date: Sat, 17 May 2025 21:10:47 +1000
Subject: [PATCH 1262/1697] remove async warning
---
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 18bceedd8..f91d9d559 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -105,7 +105,7 @@ namespace Flow.Launcher
Win32Helper.DisableControlBox(this);
}
- private async void OnLoaded(object sender, RoutedEventArgs _)
+ private void OnLoaded(object sender, RoutedEventArgs _)
{
// Check first launch
if (_settings.FirstLaunch)
From 073594fdeb365a504ac29927898136f3bcf0c076 Mon Sep 17 00:00:00 2001
From: Jeremy
Date: Sat, 17 May 2025 22:02:45 +1000
Subject: [PATCH 1263/1697] formatting
---
Flow.Launcher/ViewModel/MainViewModel.cs | 3 ---
1 file changed, 3 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index bfda18b9a..658eabde7 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1280,8 +1280,6 @@ namespace Flow.Launcher.ViewModel
// Update the query's IsReQuery property to true if this is a re-query
query.IsReQuery = isReQuery;
-
-
ICollection plugins = Array.Empty();
if (currentIsHomeQuery)
{
@@ -1345,7 +1343,6 @@ namespace Flow.Launcher.ViewModel
Results.Clear();
App.API.LogDebug(ClassName, $"Existing results are cleared for non-query");
}
-
tasks = plugins.Select(plugin => plugin.Metadata.HomeDisabled switch
{
From 0b4409711115abb8baa34d7e82b7acd4aa467f99 Mon Sep 17 00:00:00 2001
From: Jeremy
Date: Sat, 17 May 2025 22:12:35 +1000
Subject: [PATCH 1264/1697] fix encapsulation for show results
---
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 387469d24..8890c4581 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -173,7 +173,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
}
}
- public bool _showHistoryResultsForHomePage { get; set; } = false;
+ private bool _showHistoryResultsForHomePage = false;
public bool ShowHistoryResultsForHomePage
{
get => _showHistoryResultsForHomePage;
From 7399d112611cf785cba2dd9afb2f15e79451ad95 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 17 May 2025 20:27:31 +0800
Subject: [PATCH 1265/1697] Add whitespace for if
---
.../UserSettings/Settings.cs | 26 +++++++++----------
1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index 8890c4581..9d2d854f4 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -179,7 +179,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
get => _showHistoryResultsForHomePage;
set
{
- if(_showHistoryResultsForHomePage != value)
+ if (_showHistoryResultsForHomePage != value)
{
_showHistoryResultsForHomePage = value;
OnPropertyChanged();
@@ -404,29 +404,29 @@ namespace Flow.Launcher.Infrastructure.UserSettings
var list = FixedHotkeys();
// Customizeable hotkeys
- if(!string.IsNullOrEmpty(Hotkey))
+ if (!string.IsNullOrEmpty(Hotkey))
list.Add(new(Hotkey, "flowlauncherHotkey", () => Hotkey = ""));
- if(!string.IsNullOrEmpty(PreviewHotkey))
+ if (!string.IsNullOrEmpty(PreviewHotkey))
list.Add(new(PreviewHotkey, "previewHotkey", () => PreviewHotkey = ""));
- if(!string.IsNullOrEmpty(AutoCompleteHotkey))
+ if (!string.IsNullOrEmpty(AutoCompleteHotkey))
list.Add(new(AutoCompleteHotkey, "autoCompleteHotkey", () => AutoCompleteHotkey = ""));
- if(!string.IsNullOrEmpty(AutoCompleteHotkey2))
+ if (!string.IsNullOrEmpty(AutoCompleteHotkey2))
list.Add(new(AutoCompleteHotkey2, "autoCompleteHotkey", () => AutoCompleteHotkey2 = ""));
- if(!string.IsNullOrEmpty(SelectNextItemHotkey))
+ if (!string.IsNullOrEmpty(SelectNextItemHotkey))
list.Add(new(SelectNextItemHotkey, "SelectNextItemHotkey", () => SelectNextItemHotkey = ""));
- if(!string.IsNullOrEmpty(SelectNextItemHotkey2))
+ if (!string.IsNullOrEmpty(SelectNextItemHotkey2))
list.Add(new(SelectNextItemHotkey2, "SelectNextItemHotkey", () => SelectNextItemHotkey2 = ""));
- if(!string.IsNullOrEmpty(SelectPrevItemHotkey))
+ if (!string.IsNullOrEmpty(SelectPrevItemHotkey))
list.Add(new(SelectPrevItemHotkey, "SelectPrevItemHotkey", () => SelectPrevItemHotkey = ""));
- if(!string.IsNullOrEmpty(SelectPrevItemHotkey2))
+ if (!string.IsNullOrEmpty(SelectPrevItemHotkey2))
list.Add(new(SelectPrevItemHotkey2, "SelectPrevItemHotkey", () => SelectPrevItemHotkey2 = ""));
- if(!string.IsNullOrEmpty(SettingWindowHotkey))
+ if (!string.IsNullOrEmpty(SettingWindowHotkey))
list.Add(new(SettingWindowHotkey, "SettingWindowHotkey", () => SettingWindowHotkey = ""));
- if(!string.IsNullOrEmpty(OpenContextMenuHotkey))
+ if (!string.IsNullOrEmpty(OpenContextMenuHotkey))
list.Add(new(OpenContextMenuHotkey, "OpenContextMenuHotkey", () => OpenContextMenuHotkey = ""));
- if(!string.IsNullOrEmpty(SelectNextPageHotkey))
+ if (!string.IsNullOrEmpty(SelectNextPageHotkey))
list.Add(new(SelectNextPageHotkey, "SelectNextPageHotkey", () => SelectNextPageHotkey = ""));
- if(!string.IsNullOrEmpty(SelectPrevPageHotkey))
+ if (!string.IsNullOrEmpty(SelectPrevPageHotkey))
list.Add(new(SelectPrevPageHotkey, "SelectPrevPageHotkey", () => SelectPrevPageHotkey = ""));
if (!string.IsNullOrEmpty(CycleHistoryUpHotkey))
list.Add(new(CycleHistoryUpHotkey, "CycleHistoryUpHotkey", () => CycleHistoryUpHotkey = ""));
From b5a17b4a24829c657cd2178e9178320f9bfbc3b7 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 17 May 2025 21:35:52 +0800
Subject: [PATCH 1266/1697] Improve logic
---
Flow.Launcher/PublicAPIInstance.cs | 58 ++++++++++++++----------------
1 file changed, 27 insertions(+), 31 deletions(-)
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index ad48081b4..0e32ffae5 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -316,46 +316,42 @@ namespace Flow.Launcher
public void OpenDirectory(string DirectoryPath, string FileNameOrFilePath = null)
{
- string targetPath;
-
- if (FileNameOrFilePath is null)
- {
- targetPath = DirectoryPath;
- }
- else
- {
- targetPath = Path.IsPathRooted(FileNameOrFilePath)
- ? FileNameOrFilePath
- : Path.Combine(DirectoryPath, FileNameOrFilePath);
- }
-
var explorerInfo = _settings.CustomExplorer;
var explorerPath = explorerInfo.Path.Trim().ToLowerInvariant();
-
- // If explorer.exe, ignore and pass only the path to Shell
+ var targetPath = FileNameOrFilePath is null
+ ? DirectoryPath
+ : Path.IsPathRooted(FileNameOrFilePath)
+ ? FileNameOrFilePath
+ : Path.Combine(DirectoryPath, FileNameOrFilePath);
+
+ using var explorer = new Process();
if (Path.GetFileNameWithoutExtension(explorerPath) == "explorer")
{
- Process.Start(new ProcessStartInfo
+ // Windows File Manager
+ // We should ignore and pass only the path to Shell to prevent zombie explorer.exe processes
+ explorer.StartInfo = new ProcessStartInfo
{
FileName = targetPath, // Not explorer, Only path.
UseShellExecute = true // Must be true to open folder
- });
- return;
+ };
+ }
+ else
+ {
+ // Custom File Manager
+ explorer.StartInfo = new ProcessStartInfo
+ {
+ FileName = explorerInfo.Path.Replace("%d", DirectoryPath),
+ UseShellExecute = true,
+ Arguments = FileNameOrFilePath is null
+ ? explorerInfo.DirectoryArgument.Replace("%d", DirectoryPath)
+ : explorerInfo.FileArgument
+ .Replace("%d", DirectoryPath)
+ .Replace("%f", targetPath)
+ };
}
- // Custom File Manager
- var psi = new ProcessStartInfo
- {
- FileName = explorerInfo.Path.Replace("%d", DirectoryPath),
- UseShellExecute = true,
- Arguments = FileNameOrFilePath is null
- ? explorerInfo.DirectoryArgument.Replace("%d", DirectoryPath)
- : explorerInfo.FileArgument
- .Replace("%d", DirectoryPath)
- .Replace("%f", targetPath)
- };
-
- Process.Start(psi);
+ // Start the process
+ explorer.Start();
}
private void OpenUri(Uri uri, bool? inPrivate = null)
From 95eaa79c703200cdae6cca6111f66a94ef01db77 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 17 May 2025 21:36:33 +0800
Subject: [PATCH 1267/1697] Improve code logic
---
Flow.Launcher/PublicAPIInstance.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 0e32ffae5..828779f0a 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -316,6 +316,7 @@ namespace Flow.Launcher
public void OpenDirectory(string DirectoryPath, string FileNameOrFilePath = null)
{
+ using var explorer = new Process();
var explorerInfo = _settings.CustomExplorer;
var explorerPath = explorerInfo.Path.Trim().ToLowerInvariant();
var targetPath = FileNameOrFilePath is null
@@ -324,7 +325,6 @@ namespace Flow.Launcher
? FileNameOrFilePath
: Path.Combine(DirectoryPath, FileNameOrFilePath);
- using var explorer = new Process();
if (Path.GetFileNameWithoutExtension(explorerPath) == "explorer")
{
// Windows File Manager
From 87d11c0a74e4d641157f6baa2d7b197517974225 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 17 May 2025 21:37:27 +0800
Subject: [PATCH 1268/1697] Remove code comments
---
Flow.Launcher/PublicAPIInstance.cs | 2 --
1 file changed, 2 deletions(-)
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 828779f0a..796f65ae6 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -349,8 +349,6 @@ namespace Flow.Launcher
.Replace("%f", targetPath)
};
}
-
- // Start the process
explorer.Start();
}
From 8aed36e2efa7999bdef82fce688f4e1af7e9dc20 Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Sun, 18 May 2025 18:26:45 +1000
Subject: [PATCH 1269/1697] New Crowdin updates (#3531)
---
Flow.Launcher/Languages/pl.xaml | 2 +-
Plugins/Flow.Launcher.Plugin.Explorer/Languages/ar.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Explorer/Languages/cs.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Explorer/Languages/da.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Explorer/Languages/de.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Explorer/Languages/es-419.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Explorer/Languages/es.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Explorer/Languages/fr.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Explorer/Languages/he.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Explorer/Languages/it.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Explorer/Languages/ja.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Explorer/Languages/ko.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Explorer/Languages/nb.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Explorer/Languages/nl.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Explorer/Languages/pl.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-br.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-pt.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Explorer/Languages/ru.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Explorer/Languages/sk.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Explorer/Languages/sr.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Explorer/Languages/tr.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Explorer/Languages/uk-UA.xaml | 5 +++--
Plugins/Flow.Launcher.Plugin.Explorer/Languages/vi.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Explorer/Languages/zh-cn.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Explorer/Languages/zh-tw.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Program/Languages/ar.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Program/Languages/cs.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Program/Languages/da.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Program/Languages/de.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Program/Languages/es-419.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Program/Languages/es.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Program/Languages/fr.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Program/Languages/he.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Program/Languages/it.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Program/Languages/ja.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Program/Languages/ko.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Program/Languages/nb.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Program/Languages/nl.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Program/Languages/pl.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Program/Languages/pt-br.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Program/Languages/pt-pt.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Program/Languages/ru.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Program/Languages/sk.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Program/Languages/sr.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Program/Languages/tr.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Program/Languages/uk-UA.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Program/Languages/vi.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Program/Languages/zh-cn.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Program/Languages/zh-tw.xaml | 2 ++
49 files changed, 98 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher/Languages/pl.xaml b/Flow.Launcher/Languages/pl.xaml
index 7cc6dfcb1..081c8e90e 100644
--- a/Flow.Launcher/Languages/pl.xaml
+++ b/Flow.Launcher/Languages/pl.xaml
@@ -488,7 +488,7 @@ Jeśli dodasz prefiks '@' podczas wprowadzania skrótu, będzie on pasował do d
Anuluj
Aktualizacja nie powiodła się
Sprawdź połączenie i spróbuj zaktualizować ustawienia proxy do github-cloud.s3.amazonaws.com.
- Aby dokończyć proces aktualizacji Flow Launcher musi zostać zresetowany
+ Aby dokończyć proces aktualizacji Flow Launcher musi zostać zrestartowany
Następujące pliki zostaną zaktualizowane
Aktualizuj pliki
Opis aktualizacji
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ar.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ar.xaml
index db85ef7b1..0a3bfc36a 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ar.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ar.xaml
@@ -80,6 +80,8 @@
نسخ المسار
نسخ مسار العنصر الحالي إلى الحافظة
+ Copy name
+ Copy name of current item to clipboard
نسخ
نسخ الملف الحالي إلى الحافظة
نسخ المجلد الحالي إلى الحافظة
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/cs.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/cs.xaml
index 9d23e3afe..4fc248a2a 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/cs.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/cs.xaml
@@ -80,6 +80,8 @@
Kopírovat cestu
Zkopírovat cestu k aktuální položce do schránky
+ Copy name
+ Copy name of current item to clipboard
Kopírovat
Kopírovat aktuální soubor do schránky
Kopírovat aktuální složku do schránky
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/da.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/da.xaml
index 0f7619954..e0ae6d9c8 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/da.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/da.xaml
@@ -80,6 +80,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/Languages/de.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/de.xaml
index f2df655c7..1ee327adb 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/de.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/de.xaml
@@ -80,6 +80,8 @@
Pfad kopieren
Pfad des aktuellen Elements in Zwischenablage kopieren
+ Copy name
+ Copy name of current item to clipboard
Kopieren
Aktuelle Datei in Zwischenablage kopieren
Aktuellen Ordner in Zwischenablage kopieren
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/es-419.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/es-419.xaml
index 304a41c23..490096013 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/es-419.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/es-419.xaml
@@ -80,6 +80,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/Languages/es.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/es.xaml
index e144b724c..8977eb6a7 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/es.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/es.xaml
@@ -80,6 +80,8 @@
Copiar ruta
Copia la ruta del elemento actual al portapapeles
+ Copiar nombre
+ Copiar nombre del elemento actual al portapapeles
Copiar
Copia el archivo actual al portapapeles
Copia la carpeta actual al portapapeles
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/fr.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/fr.xaml
index 37d557c37..79eab8918 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/fr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/fr.xaml
@@ -80,6 +80,8 @@
Copier le chemin
Copier le chemin de l'élément actuel dans le presse-papiers
+ Copier le nom
+ Copier le nom de l'élément actuel dans le presse-papiers
Copier
Copier le fichier actuel dans le presse-papiers
Copier le dossier actuel dans le presse-papiers
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/he.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/he.xaml
index cabdd51f3..cc8415692 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/he.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/he.xaml
@@ -80,6 +80,8 @@
העתק נתיב
העתק את הנתיב של הפריט הנוכחי ללוח
+ העתק שם
+ העתק את שם הפריט הנוכחי ללוח
העתק
העתק את הקובץ הנוכחי ללוח
העתק את התיקייה הנוכחית ללוח
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/it.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/it.xaml
index eb0ef2771..492e3e03d 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/it.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/it.xaml
@@ -80,6 +80,8 @@
Copia percorso
Copia negli appunti il percorso dell'elemento corrente
+ Copy name
+ Copy name of current item to clipboard
Copia
Copia file corrente negli appunti
Copia cartella corrente negli appunti
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ja.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ja.xaml
index 29c97a651..d815e2ddc 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ja.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ja.xaml
@@ -80,6 +80,8 @@
パスをコピー
現在の項目のパスをコピー
+ Copy name
+ Copy name of current item to clipboard
コピー
現在のファイルをコピー
現在のフォルダーをコピー
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ko.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ko.xaml
index 0d96210e1..1d11556ad 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ko.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ko.xaml
@@ -80,6 +80,8 @@
경로 복사
이 항목의 경로를 클립보드에 복사
+ Copy name
+ Copy name of current item to clipboard
복사하기
이 파일을 클립보드에 복사
이 파일을 클립보드에 복사
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/nb.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/nb.xaml
index 9c908c569..3488ad2f0 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/nb.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/nb.xaml
@@ -80,6 +80,8 @@
Kopier sti
Kopier sti til gjeldende element til utklippstavlen
+ Copy name
+ Copy name of current item to clipboard
Kopier
Kopier gjeldende fil til utklippstavlen
Kopier gjeldende mappe til utklippstavlen
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/nl.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/nl.xaml
index 38e45aaa8..b6816b63f 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/nl.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/nl.xaml
@@ -80,6 +80,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/Languages/pl.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pl.xaml
index 324b8ad36..f4cecc440 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pl.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pl.xaml
@@ -80,6 +80,8 @@
Skopiuj Ścieżkę
Kopiuj ścieżkę bieżącego elementu do schowka
+ Copy name
+ Copy name of current item to clipboard
Kopiuj
Kopiuj bieżący plik do schowka
Kopiuj bieżący folder do schowka
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-br.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-br.xaml
index 058bd353f..2754a5a99 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-br.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-br.xaml
@@ -80,6 +80,8 @@
Copy path
Copy path of current item to clipboard
+ Copy name
+ Copy name of current item to clipboard
Copiar
Copy current file to clipboard
Copy current folder to clipboard
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-pt.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-pt.xaml
index 39d056e28..af7c58a95 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-pt.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-pt.xaml
@@ -80,6 +80,8 @@
Copiar caminho
Copiar caminho do item atual para área de transferência
+ Copiar nome
+ Copiar nome do item para a área de transferência
Copiar
Copiar ficheiro atual para a área de transferência
Copiar pasta atual para a área de transferência
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ru.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ru.xaml
index 911364fdf..aa67373e2 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ru.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ru.xaml
@@ -80,6 +80,8 @@
Скопировать путь
Copy path of current item to clipboard
+ Copy name
+ Copy name of current item to clipboard
Скопировать
Copy current file to clipboard
Copy current folder to clipboard
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/sk.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/sk.xaml
index 35883a09c..b538ea9e1 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/sk.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/sk.xaml
@@ -80,6 +80,8 @@
Kopírovať cestu
Skopírovať cestu k aktuálnej položke do schránky
+ Kopírovať názov
+ Skopírovať názov aktuálnej položky do schránky
Kopírovať
Skopírovať aktuálny súbor do schránky
Skopírovať aktuálny priečinok do schránky
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/sr.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/sr.xaml
index f1227df40..54e419519 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/sr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/sr.xaml
@@ -80,6 +80,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/Languages/tr.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/tr.xaml
index 1e09ba103..465a4fdd7 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/tr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/tr.xaml
@@ -80,6 +80,8 @@
Yolu kopyala
Mevcut dosya konumunu panoya kopyala
+ Copy name
+ Copy name of current item to clipboard
Kopyala
Mevcut dosyayı panoya kopyala
Mevcut klasörü panoya kopyala
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/uk-UA.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/uk-UA.xaml
index d96b5b503..4df9ddaa1 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/uk-UA.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/uk-UA.xaml
@@ -80,6 +80,8 @@
Копіювати шлях
Копіювати шлях до поточного елемента в буфер обміну
+ Copy name
+ Copy name of current item to clipboard
Копіювати
Копіювання поточного файлу в буфер обміну
Копіювати поточну папку в буфер обміну
@@ -161,6 +163,5 @@
Рідне контекстне меню
Відображати рідне контекстне меню (експериментально)
Нижче ви можете вказати елементи, які хочете включити до контекстного меню, вони можуть бути частковими (наприклад, «шир пера») або повними («Відкрити за допомогою»).
- Нижче ви можете вказати елементи, які хочете виключити з контекстного меню, вони можуть бути частковими (наприклад, «шир пера») або повними («Відкрити за допомогою»).
-
+ 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/vi.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/vi.xaml
index 81b5a2f92..1fed3d067 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/vi.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/vi.xaml
@@ -80,6 +80,8 @@
Copy đường dẫn
Sao chép đường dẫn của mục hiện tại vào clipboard
+ Copy name
+ Copy name of current item to clipboard
Sao chép
Sao chép tập tin hiện tại vào clipboard
Copy current folder to clipboard
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/zh-cn.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/zh-cn.xaml
index 64831ea13..67253d1e1 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/zh-cn.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/zh-cn.xaml
@@ -80,6 +80,8 @@
复制路径
复制当前结果的路径到剪贴板
+ Copy name
+ Copy name of current item to clipboard
复制
复制当前文件到剪贴板
复制当前文件夹到剪贴板
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/zh-tw.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/zh-tw.xaml
index 9e9697255..873a3866d 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/zh-tw.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/zh-tw.xaml
@@ -80,6 +80,8 @@
複製路徑
Copy path of current item to clipboard
+ Copy name
+ Copy name of current item to clipboard
複製
Copy current file to clipboard
Copy current folder to clipboard
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/ar.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/ar.xaml
index d352368cb..c65fa196b 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/ar.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/ar.xaml
@@ -46,6 +46,8 @@
الرجاء تحديد مصدر برنامج
هل أنت متأكد أنك تريد حذف مصادر البرامج المحددة؟
+ Please select program sources that are not added by you
+ Please select program sources that are added by you
مصدر برنامج آخر بنفس الموقع موجود بالفعل.
مصدر البرنامج
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/cs.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/cs.xaml
index ca57bf027..b694c5bdd 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/cs.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/cs.xaml
@@ -46,6 +46,8 @@
Prosím vyberte zdroj programu
Jste si jisti, že chcete odstranit vybrané zdroje programů?
+ Please select program sources that are not added by you
+ Please select program sources that are added by you
Již existuje jiný zdroj programu se stejným umístěním.
Zdroj programu
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/da.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/da.xaml
index a0f09a3b5..5958eba32 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/da.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/da.xaml
@@ -46,6 +46,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
Another program source with the same location already exists.
Program Source
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/de.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/de.xaml
index ec5d273d6..7919ae7cb 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/de.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/de.xaml
@@ -46,6 +46,8 @@
Bitte wählen Sie eine Programmquelle aus
Sind Sie sicher, dass Sie die ausgewählten Programmquellen löschen wollen?
+ Please select program sources that are not added by you
+ Please select program sources that are added by you
Eine andere Programmquelle mit dem gleichen Ort ist bereits vorhanden.
Programmquelle
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/es-419.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/es-419.xaml
index d9ffa668c..9818e4226 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/es-419.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/es-419.xaml
@@ -46,6 +46,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
Another program source with the same location already exists.
Program Source
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/es.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/es.xaml
index d0b6851d9..2e1eadb2b 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/es.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/es.xaml
@@ -46,6 +46,8 @@
Por favor, seleccione la ruta del programa
¿Está seguro de que desea eliminar las fuentes del programa seleccionadas?
+ Please select program sources that are not added by you
+ Please select program sources that are added by you
Ya existe otra fuente de programa con la misma ubicación.
Fuente de Programa
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/fr.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/fr.xaml
index e6fd67936..e509a875f 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/fr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/fr.xaml
@@ -46,6 +46,8 @@
Veuillez sélectionner une source de programme
Êtes-vous sûr de vouloir supprimer les sources de programmes sélectionnées ?
+ Veuillez sélectionner les sources de programmes qui n'ont pas été ajoutées par vous-même
+ Veuillez sélectionner les sources de programmes qui ont été ajoutées par vous-même
Il existe déjà une autre source de programme ayant le même emplacement.
Source du programme
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/he.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/he.xaml
index 88053ac57..83f034646 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/he.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/he.xaml
@@ -46,6 +46,8 @@
אנא בחר מקור תוכנה
האם אתה בטוח שברצונך למחוק את מקורות התוכניות שנבחרו?
+ Please select program sources that are not added by you
+ Please select program sources that are added by you
מקור תוכנה נוסף עם אותו מיקום כבר קיים.
מקור תוכנה
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/it.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/it.xaml
index 5004d41cf..bb97a0085 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/it.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/it.xaml
@@ -46,6 +46,8 @@
Seleziona la sorgente del programma
Sei sicuro di voler cancellare le sorgenti dei programmi selezionate?
+ 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/Languages/ja.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/ja.xaml
index 96ca3af60..4a1d815ec 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/ja.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/ja.xaml
@@ -46,6 +46,8 @@
Please select a program source
Are your sure to delete {0}?
+ 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/Languages/ko.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/ko.xaml
index 266aa4b45..f2ac75762 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/ko.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/ko.xaml
@@ -46,6 +46,8 @@
프로그램 검색 출처를 선택하세요
선택하신 프로그램 출처를 삭제하시겠습니까?
+ 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/Languages/nb.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/nb.xaml
index c4b218204..25018d752 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/nb.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/nb.xaml
@@ -46,6 +46,8 @@
Vennligst velg en programkilde
Er du sikker på at du vil slette de valgte programkildene?
+ Please select program sources that are not added by you
+ Please select program sources that are added by you
Det finnes allerede en annen programkilde med samme plassering.
Programkilde
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/nl.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/nl.xaml
index 495296694..eb8a6f1a6 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/nl.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/nl.xaml
@@ -46,6 +46,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
Another program source with the same location already exists.
Program Source
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/pl.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/pl.xaml
index f38fd9623..4d1483eee 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/pl.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/pl.xaml
@@ -46,6 +46,8 @@
Musisz wybrać katalog programu
Czy na pewno chcesz usunąć wybrane źródła programów?
+ Please select program sources that are not added by you
+ Please select program sources that are added by you
Inne źródło programu z tą samą lokalizacją już istnieje.
Źródło programu
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/pt-br.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/pt-br.xaml
index 3ff8be551..978c2833d 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/pt-br.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/pt-br.xaml
@@ -46,6 +46,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
Another program source with the same location already exists.
Program Source
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/pt-pt.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/pt-pt.xaml
index aa3c500a3..cc3e280b2 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/pt-pt.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/pt-pt.xaml
@@ -46,6 +46,8 @@
Por favor selecione uma origem de programas
Tem a certeza de que deseja remover as origens selecionadas?
+ Selecione as origens de programas NÃO adicionadas por si
+ Selecione as origens de programas adicionadas por si
Já existe uma origem de programas com esta localização.
Origem de programas
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/ru.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/ru.xaml
index a75a6d836..7624d6517 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/ru.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/ru.xaml
@@ -46,6 +46,8 @@
Пожалуйста, выберите источник программы
Вы уверены, что хотите удалить выбранные источники программ?
+ Please select program sources that are not added by you
+ Please select program sources that are added by you
Другой источник программы с таким же расположением уже существует.
Источник программы
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/sk.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/sk.xaml
index 7fda65160..b30b56a5b 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/sk.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/sk.xaml
@@ -46,6 +46,8 @@
Prosím, zadajte zdroj programu
Naozaj chcete odstrániť vybrané zdroje programov?
+ Vyberte zdroje programov, ktoré ste nepridali vy
+ Vyberte zdroje programov, ktoré ste pridali vy
Iný zdroj programu s rovnakým umiestnením už existuje.
Zdroj programu
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/sr.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/sr.xaml
index f2da895b0..a79655a7b 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/sr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/sr.xaml
@@ -46,6 +46,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
Another program source with the same location already exists.
Program Source
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/tr.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/tr.xaml
index 6bda659dd..126613065 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/tr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/tr.xaml
@@ -46,6 +46,8 @@
İşlem yapmak istediğiniz klasörü seçin.
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
Another program source with the same location already exists.
Program Source
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/uk-UA.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/uk-UA.xaml
index 3686925a9..290954d5f 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/uk-UA.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/uk-UA.xaml
@@ -46,6 +46,8 @@
Будь ласка, виберіть джерело програми
Ви впевнені, що хочете видалити вибрані джерела програм?
+ Please select program sources that are not added by you
+ Please select program sources that are added by you
Інше програмне джерело з тим самим розташуванням вже існує.
Вихідний код програми
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/vi.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/vi.xaml
index 6b238c638..0dede0f8b 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/vi.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/vi.xaml
@@ -46,6 +46,8 @@
Hãy chọn một nguồn dữ liệu
Bạn có chắc chắn là muốn xóa các đặt hàng đã chọn?
+ Please select program sources that are not added by you
+ Please select program sources that are added by you
Đã tồn tại một nguồn chương trình khác có cùng vị trí.
Nguồn 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 b36b72b9b..6bafe86e0 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/zh-cn.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/zh-cn.xaml
@@ -46,6 +46,8 @@
请先选择一项
您确定要删除选定的程序源吗?
+ Please select program sources that are not added by you
+ Please select program sources that are added by you
相同位置存在另一个程序源。
程序源
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/zh-tw.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/zh-tw.xaml
index 084adfbac..a8ff4ecbc 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/zh-tw.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/zh-tw.xaml
@@ -46,6 +46,8 @@
請先選擇一項
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
Another program source with the same location already exists.
Program Source
From f38bf674e060c3abbf8eb5519667a2f72875fdcd Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Sun, 18 May 2025 22:15:44 +1000
Subject: [PATCH 1270/1697] add publish to Chocolatey dispatch event
---
.github/workflows/release_deploy.yml | 34 ++++++++++++++++++++++++++++
.github/workflows/website_deploy.yml | 21 -----------------
2 files changed, 34 insertions(+), 21 deletions(-)
create mode 100644 .github/workflows/release_deploy.yml
delete mode 100644 .github/workflows/website_deploy.yml
diff --git a/.github/workflows/release_deploy.yml b/.github/workflows/release_deploy.yml
new file mode 100644
index 000000000..028f0045a
--- /dev/null
+++ b/.github/workflows/release_deploy.yml
@@ -0,0 +1,34 @@
+---
+
+name: New Release Deployments
+on:
+ release:
+ types: [published]
+ workflow_dispatch:
+
+jobs:
+ deploy-website:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Trigger dispatch event for deploying website
+ 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_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 website failed, HTTP status code is $http_status"; exit 1; fi
+
+ publish-chocolatey:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Trigger dispatch event for publishing to Chocolatey
+ 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.Publish_Chocolatey }}" \
+ https://api.github.com/repos/Flow-Launcher/chocolatey-package/dispatches \
+ -d '{"event_type":"publish"}')
+ if [ "$http_status" -ne 204 ]; then echo "Error: Publish Chocolatey Packaged failed, HTTP status code is $http_status"; exit 1; fi
diff --git a/.github/workflows/website_deploy.yml b/.github/workflows/website_deploy.yml
deleted file mode 100644
index 2d44e4a2c..000000000
--- a/.github/workflows/website_deploy.yml
+++ /dev/null
@@ -1,21 +0,0 @@
----
-
-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_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 ec7ab007d044fd0f6bfad469c5628b284d3c7370 Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Sun, 18 May 2025 22:23:10 +1000
Subject: [PATCH 1271/1697] fix typo
---
.github/workflows/release_deploy.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/release_deploy.yml b/.github/workflows/release_deploy.yml
index 028f0045a..9e082b95f 100644
--- a/.github/workflows/release_deploy.yml
+++ b/.github/workflows/release_deploy.yml
@@ -31,4 +31,4 @@ jobs:
-H "Authorization: Bearer ${{ secrets.Publish_Chocolatey }}" \
https://api.github.com/repos/Flow-Launcher/chocolatey-package/dispatches \
-d '{"event_type":"publish"}')
- if [ "$http_status" -ne 204 ]; then echo "Error: Publish Chocolatey Packaged failed, HTTP status code is $http_status"; exit 1; fi
+ if [ "$http_status" -ne 204 ]; then echo "Error: Publish Chocolatey package failed, HTTP status code is $http_status"; exit 1; fi
From b878532cdddfef9833ac384d0ff7672782c0803d Mon Sep 17 00:00:00 2001
From: Jeremy
Date: Mon, 19 May 2025 22:19:35 +1000
Subject: [PATCH 1272/1697] unify plugin versions to flow main version
---
appveyor.yml | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/appveyor.yml b/appveyor.yml
index af5aaefdc..74b86fc50 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -8,6 +8,14 @@ init:
{
$env:prereleaseTag = "{0}.{1}.{2}.{3}" -f $version.Major, $version.Minor, $version.Build, $version.Revision
}
+
+ $jsonFiles = Get-ChildItem -Path ".\Plugins\*\plugin.json"
+ foreach ($file in $jsonFiles) {
+ $plugin_old_ver = Get-Content $file.FullName -Raw | ConvertFrom-Json
+ (Get-Content $file) -replace '"Version"\s*:\s*".*?"', "`"Version`": `"$env:flowVersion`"" | Set-Content $file
+ $plugin_new_ver = Get-Content $file.FullName -Raw | ConvertFrom-Json
+ Write-Host "Updated" $plugin_old_ver.Name "version from" $plugin_old_ver.Version "to" $plugin_new_ver.Version
+ }
- sc config WSearch start= auto # Starts Windows Search service- Needed for running ExplorerTest
- net start WSearch
From 94cec8aa1bdbec9f435de64e0a8c27237362e1b3 Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Tue, 20 May 2025 12:43:26 +1000
Subject: [PATCH 1273/1697] move plugin version bump to build step
---
appveyor.yml | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/appveyor.yml b/appveyor.yml
index 74b86fc50..5902f09f1 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -8,14 +8,6 @@ init:
{
$env:prereleaseTag = "{0}.{1}.{2}.{3}" -f $version.Major, $version.Minor, $version.Build, $version.Revision
}
-
- $jsonFiles = Get-ChildItem -Path ".\Plugins\*\plugin.json"
- foreach ($file in $jsonFiles) {
- $plugin_old_ver = Get-Content $file.FullName -Raw | ConvertFrom-Json
- (Get-Content $file) -replace '"Version"\s*:\s*".*?"', "`"Version`": `"$env:flowVersion`"" | Set-Content $file
- $plugin_new_ver = Get-Content $file.FullName -Raw | ConvertFrom-Json
- Write-Host "Updated" $plugin_old_ver.Name "version from" $plugin_old_ver.Version "to" $plugin_new_ver.Version
- }
- sc config WSearch start= auto # Starts Windows Search service- Needed for running ExplorerTest
- net start WSearch
@@ -34,7 +26,16 @@ image: Visual Studio 2022
platform: Any CPU
configuration: Release
before_build:
-- ps: nuget restore
+- ps: |
+ nuget restore
+
+ $jsonFiles = Get-ChildItem -Path ".\Plugins\*\plugin.json"
+ foreach ($file in $jsonFiles) {
+ $plugin_old_ver = Get-Content $file.FullName -Raw | ConvertFrom-Json
+ (Get-Content $file) -replace '"Version"\s*:\s*".*?"', "`"Version`": `"$env:flowVersion`"" | Set-Content $file
+ $plugin_new_ver = Get-Content $file.FullName -Raw | ConvertFrom-Json
+ Write-Host "Updated" $plugin_old_ver.Name "version from" $plugin_old_ver.Version "to" $plugin_new_ver.Version
+ }
build:
project: Flow.Launcher.sln
verbosity: minimal
From 2b9529d2f97eb767117350d07f5ceef2e8d225ba Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Tue, 20 May 2025 09:06:11 +0000
Subject: [PATCH 1274/1697] set all of plugins' version to default 1.0.0
---
Plugins/Flow.Launcher.Plugin.BrowserBookmark/plugin.json | 2 +-
Plugins/Flow.Launcher.Plugin.Calculator/plugin.json | 2 +-
Plugins/Flow.Launcher.Plugin.Explorer/plugin.json | 2 +-
Plugins/Flow.Launcher.Plugin.PluginIndicator/plugin.json | 2 +-
Plugins/Flow.Launcher.Plugin.PluginsManager/plugin.json | 2 +-
Plugins/Flow.Launcher.Plugin.ProcessKiller/plugin.json | 2 +-
Plugins/Flow.Launcher.Plugin.Program/plugin.json | 2 +-
Plugins/Flow.Launcher.Plugin.Shell/plugin.json | 2 +-
Plugins/Flow.Launcher.Plugin.Sys/plugin.json | 2 +-
Plugins/Flow.Launcher.Plugin.Url/plugin.json | 2 +-
Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json | 2 +-
Plugins/Flow.Launcher.Plugin.WindowsSettings/plugin.json | 2 +-
12 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/plugin.json b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/plugin.json
index 519141f6c..30e34f62d 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/plugin.json
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/plugin.json
@@ -4,7 +4,7 @@
"Name": "Browser Bookmarks",
"Description": "Search your browser bookmarks",
"Author": "qianlifeng, Ioannis G.",
- "Version": "3.3.4",
+ "Version": "1.0.0",
"Language": "csharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.BrowserBookmark.dll",
diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/plugin.json b/Plugins/Flow.Launcher.Plugin.Calculator/plugin.json
index 99e185928..485babd26 100644
--- a/Plugins/Flow.Launcher.Plugin.Calculator/plugin.json
+++ b/Plugins/Flow.Launcher.Plugin.Calculator/plugin.json
@@ -4,7 +4,7 @@
"Name": "Calculator",
"Description": "Provide mathematical calculations.(Try 5*3-2 in Flow Launcher)",
"Author": "cxfksword",
- "Version": "3.1.5",
+ "Version": "1.0.0",
"Language": "csharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.Calculator.dll",
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/plugin.json b/Plugins/Flow.Launcher.Plugin.Explorer/plugin.json
index d2440ab61..5eea2646e 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/plugin.json
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/plugin.json
@@ -11,7 +11,7 @@
"Name": "Explorer",
"Description": "Find and manage files and folders via Windows Search or Everything",
"Author": "Jeremy Wu",
- "Version": "3.2.4",
+ "Version": "1.0.0",
"Language": "csharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.Explorer.dll",
diff --git a/Plugins/Flow.Launcher.Plugin.PluginIndicator/plugin.json b/Plugins/Flow.Launcher.Plugin.PluginIndicator/plugin.json
index 2b4870792..7e6a2e613 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginIndicator/plugin.json
+++ b/Plugins/Flow.Launcher.Plugin.PluginIndicator/plugin.json
@@ -4,7 +4,7 @@
"Name": "Plugin Indicator",
"Description": "Provides plugin action keyword suggestions",
"Author": "qianlifeng",
- "Version": "3.0.7",
+ "Version": "1.0.0",
"Language": "csharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.PluginIndicator.dll",
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/plugin.json b/Plugins/Flow.Launcher.Plugin.PluginsManager/plugin.json
index df5a2c784..327011ac3 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/plugin.json
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/plugin.json
@@ -6,7 +6,7 @@
"Name": "Plugins Manager",
"Description": "Management of installing, uninstalling or updating Flow Launcher plugins",
"Author": "Jeremy Wu",
- "Version": "3.2.4",
+ "Version": "1.0.0",
"Language": "csharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.PluginsManager.dll",
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/plugin.json b/Plugins/Flow.Launcher.Plugin.ProcessKiller/plugin.json
index 956c4b4e1..0379194c4 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/plugin.json
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/plugin.json
@@ -4,7 +4,7 @@
"Name":"Process Killer",
"Description":"Kill running processes from Flow",
"Author":"Flow-Launcher",
- "Version":"3.0.8",
+ "Version": "1.0.0",
"Language":"csharp",
"Website":"https://github.com/Flow-Launcher/Flow.Launcher.Plugin.ProcessKiller",
"IcoPath":"Images\\app.png",
diff --git a/Plugins/Flow.Launcher.Plugin.Program/plugin.json b/Plugins/Flow.Launcher.Plugin.Program/plugin.json
index 5a95e75f4..0316a2397 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/plugin.json
+++ b/Plugins/Flow.Launcher.Plugin.Program/plugin.json
@@ -4,7 +4,7 @@
"Name": "Program",
"Description": "Search programs in Flow.Launcher",
"Author": "qianlifeng",
- "Version": "3.3.4",
+ "Version": "1.0.0",
"Language": "csharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.Program.dll",
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/plugin.json b/Plugins/Flow.Launcher.Plugin.Shell/plugin.json
index 681e8f751..36f9b8e00 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/plugin.json
+++ b/Plugins/Flow.Launcher.Plugin.Shell/plugin.json
@@ -4,7 +4,7 @@
"Name": "Shell",
"Description": "Provide executing commands from Flow Launcher",
"Author": "qianlifeng",
- "Version": "3.2.5",
+ "Version": "1.0.0",
"Language": "csharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.Shell.dll",
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/plugin.json b/Plugins/Flow.Launcher.Plugin.Sys/plugin.json
index 90ca264cc..68ce6feb1 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/plugin.json
+++ b/Plugins/Flow.Launcher.Plugin.Sys/plugin.json
@@ -4,7 +4,7 @@
"Name": "System Commands",
"Description": "Provide System related commands. e.g. shutdown,lock, setting etc.",
"Author": "qianlifeng",
- "Version": "3.1.7",
+ "Version": "1.0.0",
"Language": "csharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.Sys.dll",
diff --git a/Plugins/Flow.Launcher.Plugin.Url/plugin.json b/Plugins/Flow.Launcher.Plugin.Url/plugin.json
index 73d9bff30..9f5576ba9 100644
--- a/Plugins/Flow.Launcher.Plugin.Url/plugin.json
+++ b/Plugins/Flow.Launcher.Plugin.Url/plugin.json
@@ -4,7 +4,7 @@
"Name": "URL",
"Description": "Open the typed URL from Flow Launcher",
"Author": "qianlifeng",
- "Version": "3.0.8",
+ "Version": "1.0.0",
"Language": "csharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.Url.dll",
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json b/Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json
index c8b6310a7..b4153feb1 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json
@@ -27,7 +27,7 @@
"Name": "Web Searches",
"Description": "Provide the web search ability",
"Author": "qianlifeng",
- "Version": "3.1.4",
+ "Version": "1.0.0",
"Language": "csharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.WebSearch.dll",
diff --git a/Plugins/Flow.Launcher.Plugin.WindowsSettings/plugin.json b/Plugins/Flow.Launcher.Plugin.WindowsSettings/plugin.json
index 413a555d3..64743b3d8 100644
--- a/Plugins/Flow.Launcher.Plugin.WindowsSettings/plugin.json
+++ b/Plugins/Flow.Launcher.Plugin.WindowsSettings/plugin.json
@@ -4,7 +4,7 @@
"Description": "Search settings inside Control Panel and Settings App",
"Name": "Windows Settings",
"Author": "TobiasSekan",
- "Version": "4.0.12",
+ "Version": "1.0.0",
"Language": "csharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.WindowsSettings.dll",
From 037b800f4a6d673f163e83e4c121c86f3fe777ac Mon Sep 17 00:00:00 2001
From: DB p
Date: Tue, 20 May 2025 17:56:24 +0900
Subject: [PATCH 1275/1697] Add file manager path validation and error handling
in SelectFileManagerWindow
---
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 027eb3f92..f00f42ac0 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -226,8 +226,8 @@ namespace Flow.Launcher.Infrastructure.UserSettings
new()
{
Name = "Files",
- Path = "Files",
- DirectoryArgument = "-select \"%d\"",
+ Path = "Files-Stable",
+ DirectoryArgument = "\"%d\"",
FileArgument = "-select \"%f\""
}
};
From 2c7fb93d3710bd4cee3437b7bd4e090d23d37e2a Mon Sep 17 00:00:00 2001
From: DB p
Date: Tue, 20 May 2025 18:49:38 +0900
Subject: [PATCH 1276/1697] Add error handling and validation for custom file
manager paths
---
Flow.Launcher/Languages/en.xaml | 6 ++
Flow.Launcher/PublicAPIInstance.cs | 83 ++++++++++++-------
Flow.Launcher/SelectFileManagerWindow.xaml.cs | 56 ++++++++++++-
3 files changed, 114 insertions(+), 31 deletions(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 22ab2016c..299fe3029 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -373,6 +373,8 @@
File Manager Path
Arg For Folder
Arg For File
+ The path for the file manager '{0}' could not be found: {1}\n\nDo you want to continue?
+ File Manager Path Error
Default Web Browser
@@ -462,6 +464,10 @@
1. Upload log file: {0}
2. Copy below exception message
+
+ An error occurred while opening the folder.:\n{0}
+ Error
+
Please wait...
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 796f65ae6..84448a685 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -316,40 +316,63 @@ namespace Flow.Launcher
public void OpenDirectory(string DirectoryPath, string FileNameOrFilePath = null)
{
- using var explorer = new Process();
- var explorerInfo = _settings.CustomExplorer;
- var explorerPath = explorerInfo.Path.Trim().ToLowerInvariant();
- var targetPath = FileNameOrFilePath is null
- ? DirectoryPath
- : Path.IsPathRooted(FileNameOrFilePath)
- ? FileNameOrFilePath
- : Path.Combine(DirectoryPath, FileNameOrFilePath);
+ try
+ {
+ using var explorer = new Process();
+ var explorerInfo = _settings.CustomExplorer;
+ var explorerPath = explorerInfo.Path.Trim().ToLowerInvariant();
+ var targetPath = FileNameOrFilePath is null
+ ? DirectoryPath
+ : Path.IsPathRooted(FileNameOrFilePath)
+ ? FileNameOrFilePath
+ : Path.Combine(DirectoryPath, FileNameOrFilePath);
- if (Path.GetFileNameWithoutExtension(explorerPath) == "explorer")
- {
- // Windows File Manager
- // We should ignore and pass only the path to Shell to prevent zombie explorer.exe processes
- explorer.StartInfo = new ProcessStartInfo
+ if (Path.GetFileNameWithoutExtension(explorerPath) == "explorer")
{
- FileName = targetPath, // Not explorer, Only path.
- UseShellExecute = true // Must be true to open folder
- };
- }
- else
- {
- // Custom File Manager
- explorer.StartInfo = new ProcessStartInfo
+ // Windows File Manager
+ explorer.StartInfo = new ProcessStartInfo
+ {
+ FileName = targetPath,
+ UseShellExecute = true
+ };
+ }
+ else
{
- FileName = explorerInfo.Path.Replace("%d", DirectoryPath),
- UseShellExecute = true,
- Arguments = FileNameOrFilePath is null
- ? explorerInfo.DirectoryArgument.Replace("%d", DirectoryPath)
- : explorerInfo.FileArgument
- .Replace("%d", DirectoryPath)
- .Replace("%f", targetPath)
- };
+ // Custom File Manager
+ explorer.StartInfo = new ProcessStartInfo
+ {
+ FileName = explorerInfo.Path.Replace("%d", DirectoryPath),
+ UseShellExecute = true,
+ Arguments = FileNameOrFilePath is null
+ ? explorerInfo.DirectoryArgument.Replace("%d", DirectoryPath)
+ : explorerInfo.FileArgument
+ .Replace("%d", DirectoryPath)
+ .Replace("%f", targetPath)
+ };
+ }
+
+ explorer.Start();
+ }
+ catch (System.ComponentModel.Win32Exception ex) when (ex.NativeErrorCode == 2)
+ {
+ // File Manager not found
+ MessageBoxEx.Show(
+ string.Format(GetTranslation("fileManagerNotFound"), ex.Message),
+ GetTranslation("fileManagerNotFoundTitle"),
+ MessageBoxButton.OK,
+ MessageBoxImage.Error
+ );
+ }
+ catch (Exception ex)
+ {
+ // Other exceptions
+ MessageBoxEx.Show(
+ string.Format(GetTranslation("folderOpenError"), ex.Message),
+ GetTranslation("errorTitle"),
+ MessageBoxButton.OK,
+ MessageBoxImage.Error
+ );
}
- explorer.Start();
}
private void OpenUri(Uri uri, bool? inPrivate = null)
diff --git a/Flow.Launcher/SelectFileManagerWindow.xaml.cs b/Flow.Launcher/SelectFileManagerWindow.xaml.cs
index bf94ddacb..d2f7ae764 100644
--- a/Flow.Launcher/SelectFileManagerWindow.xaml.cs
+++ b/Flow.Launcher/SelectFileManagerWindow.xaml.cs
@@ -1,5 +1,8 @@
-using System.Collections.ObjectModel;
+using System;
+using System.Collections.ObjectModel;
using System.ComponentModel;
+using System.Diagnostics;
+using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
@@ -43,11 +46,62 @@ namespace Flow.Launcher
private void btnDone_Click(object sender, RoutedEventArgs e)
{
+ // Check if the selected file manager path is valid
+ if (!IsFileManagerValid(CustomExplorer.Path))
+ {
+ MessageBoxResult result = MessageBoxEx.Show(
+ string.Format((string)Application.Current.FindResource("fileManagerPathNotFound"),
+ CustomExplorer.Name, CustomExplorer.Path),
+ (string)Application.Current.FindResource("fileManagerPathError"),
+ MessageBoxButton.YesNo,
+ MessageBoxImage.Warning);
+
+ if (result == MessageBoxResult.No)
+ {
+ return;
+ }
+ }
+
_settings.CustomExplorerList = CustomExplorers.ToList();
_settings.CustomExplorerIndex = SelectedCustomExplorerIndex;
Close();
}
+ private bool IsFileManagerValid(string path)
+ {
+ if (string.Equals(path, "explorer", StringComparison.OrdinalIgnoreCase))
+ return true;
+
+ if (Path.IsPathRooted(path))
+ {
+ return File.Exists(path);
+ }
+
+ try
+ {
+ var process = new Process
+ {
+ StartInfo = new ProcessStartInfo
+ {
+ FileName = "where",
+ Arguments = path,
+ RedirectStandardOutput = true,
+ UseShellExecute = false,
+ CreateNoWindow = true
+ }
+ };
+ process.Start();
+ string output = process.StandardOutput.ReadToEnd();
+ process.WaitForExit();
+
+ return !string.IsNullOrEmpty(output);
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
private void btnAdd_Click(object sender, RoutedEventArgs e)
{
CustomExplorers.Add(new()
From cc80221903577e21cc8123159d0f15ddde60a250 Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Tue, 20 May 2025 20:00:13 +1000
Subject: [PATCH 1277/1697] Version bump for release
---
appveyor.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/appveyor.yml b/appveyor.yml
index 5902f09f1..fa0b5956b 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,4 +1,4 @@
-version: '1.19.5.{build}'
+version: '1.20.0.{build}'
init:
- ps: |
From aadfde09d5745c14af96af70227360967b39edd4 Mon Sep 17 00:00:00 2001
From: DB p
Date: Tue, 20 May 2025 20:32:46 +0900
Subject: [PATCH 1278/1697] Add tips for file manager usage and improve error
messages
---
Flow.Launcher/Languages/en.xaml | 10 +++-
Flow.Launcher/SelectFileManagerWindow.xaml | 15 ++++--
Flow.Launcher/SelectFileManagerWindow.xaml.cs | 46 +++++++++++++++++++
3 files changed, 66 insertions(+), 5 deletions(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 299fe3029..186f6bd3e 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -366,6 +366,8 @@
Select File Manager
+ Do you use Files?
+ Depending on the version, Files may use either "Files" or "Files-stable" as its path. (This can vary depending on which version you're using.) For more details, see:
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
@@ -373,7 +375,7 @@
File Manager Path
Arg For Folder
Arg For File
- The path for the file manager '{0}' could not be found: {1}\n\nDo you want to continue?
+ The path for the file manager '{0}' could not be found: '{1}' Do you want to continue?
File Manager Path Error
@@ -465,8 +467,12 @@
2. Copy below exception message
- An error occurred while opening the folder.:\n{0}
+ File Manager Error
+
+ The specified file manager could not be found. Please check the Custom File Manager setting under Settings >General.
+
Error
+ An error occurred while opening the folder. {0}
Please wait...
diff --git a/Flow.Launcher/SelectFileManagerWindow.xaml b/Flow.Launcher/SelectFileManagerWindow.xaml
index 0287af9b0..fbdc2c3b2 100644
--- a/Flow.Launcher/SelectFileManagerWindow.xaml
+++ b/Flow.Launcher/SelectFileManagerWindow.xaml
@@ -73,9 +73,18 @@
+
-
-
+
+
+ Fill="{StaticResource SeparatorForeground}" />
+ {
+ Process.Start(new ProcessStartInfo
+ {
+ FileName = args.Uri.AbsoluteUri,
+ UseShellExecute = true
+ });
+ args.Handled = true;
+ };
+
+ textBlock.Inlines.Add(hyperlink);
+
+ var tipsDialog = new ContentDialog()
+ {
+ Owner = Window.GetWindow(sender as DependencyObject),
+ Title = (string)Application.Current.Resources["fileManager_files_btn"],
+ Content = textBlock,
+ PrimaryButtonText = (string)Application.Current.Resources["commonOK"],
+ CornerRadius = new CornerRadius(8),
+ Style = (Style)Application.Current.Resources["ContentDialog"]
+ };
+
+ await tipsDialog.ShowAsync();
+ }
+
private void btnAdd_Click(object sender, RoutedEventArgs e)
{
CustomExplorers.Add(new()
From f26226393488f7b03d711d18deca7d3a46ef8e6b Mon Sep 17 00:00:00 2001
From: DB p
Date: Tue, 20 May 2025 22:07:41 +0900
Subject: [PATCH 1279/1697] Add hyperlink to learn more about file manager
usage in settings dialog
---
Flow.Launcher/Languages/en.xaml | 1 +
Flow.Launcher/SelectFileManagerWindow.xaml | 19 +++++++++++++------
Flow.Launcher/SelectFileManagerWindow.xaml.cs | 10 ++++++++++
3 files changed, 24 insertions(+), 6 deletions(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 186f6bd3e..7d1635bab 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -367,6 +367,7 @@
Select File Manager
Do you use Files?
+ Learn more
Depending on the version, Files may use either "Files" or "Files-stable" as its path. (This can vary depending on which version you're using.) For more details, see:
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.
diff --git a/Flow.Launcher/SelectFileManagerWindow.xaml b/Flow.Launcher/SelectFileManagerWindow.xaml
index fbdc2c3b2..5e01a4a5f 100644
--- a/Flow.Launcher/SelectFileManagerWindow.xaml
+++ b/Flow.Launcher/SelectFileManagerWindow.xaml
@@ -73,12 +73,19 @@
-
+
+
+
+
+
+
+
+
Date: Tue, 20 May 2025 21:35:26 +0800
Subject: [PATCH 1280/1697] Remove unused function
---
Flow.Launcher/MessageBoxEx.xaml.cs | 3 ---
1 file changed, 3 deletions(-)
diff --git a/Flow.Launcher/MessageBoxEx.xaml.cs b/Flow.Launcher/MessageBoxEx.xaml.cs
index a55aeb811..c084b5149 100644
--- a/Flow.Launcher/MessageBoxEx.xaml.cs
+++ b/Flow.Launcher/MessageBoxEx.xaml.cs
@@ -22,9 +22,6 @@ namespace Flow.Launcher
InitializeComponent();
}
- public static MessageBoxResult Show(string messageBoxText)
- => Show(messageBoxText, string.Empty, MessageBoxButton.OK, MessageBoxImage.None, MessageBoxResult.OK);
-
public static MessageBoxResult Show(
string messageBoxText,
string caption = "",
From 3beb4e9c56b3a631b62f16c74cb423384bae753f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 20 May 2025 21:37:06 +0800
Subject: [PATCH 1281/1697] Use api functions instead
---
Flow.Launcher/PublicAPIInstance.cs | 4 ++--
Flow.Launcher/SelectFileManagerWindow.xaml.cs | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 84448a685..6516388ac 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -356,7 +356,7 @@ namespace Flow.Launcher
catch (System.ComponentModel.Win32Exception ex) when (ex.NativeErrorCode == 2)
{
// File Manager not found
- MessageBoxEx.Show(
+ ShowMsgBox(
string.Format(GetTranslation("fileManagerNotFound"), ex.Message),
GetTranslation("fileManagerNotFoundTitle"),
MessageBoxButton.OK,
@@ -366,7 +366,7 @@ namespace Flow.Launcher
catch (Exception ex)
{
// Other exceptions
- MessageBoxEx.Show(
+ ShowMsgBox(
string.Format(GetTranslation("folderOpenError"), ex.Message),
GetTranslation("errorTitle"),
MessageBoxButton.OK,
diff --git a/Flow.Launcher/SelectFileManagerWindow.xaml.cs b/Flow.Launcher/SelectFileManagerWindow.xaml.cs
index 2ab134c85..e77d6f899 100644
--- a/Flow.Launcher/SelectFileManagerWindow.xaml.cs
+++ b/Flow.Launcher/SelectFileManagerWindow.xaml.cs
@@ -61,7 +61,7 @@ namespace Flow.Launcher
// Check if the selected file manager path is valid
if (!IsFileManagerValid(CustomExplorer.Path))
{
- MessageBoxResult result = MessageBoxEx.Show(
+ var result = App.API.ShowMsgBox(
string.Format((string)Application.Current.FindResource("fileManagerPathNotFound"),
CustomExplorer.Name, CustomExplorer.Path),
(string)Application.Current.FindResource("fileManagerPathError"),
From af4375b60e194513524340e05a5c03df749a6712 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 20 May 2025 21:42:16 +0800
Subject: [PATCH 1282/1697] Improve code quality
---
Flow.Launcher/SelectFileManagerWindow.xaml.cs | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher/SelectFileManagerWindow.xaml.cs b/Flow.Launcher/SelectFileManagerWindow.xaml.cs
index e77d6f899..01517522d 100644
--- a/Flow.Launcher/SelectFileManagerWindow.xaml.cs
+++ b/Flow.Launcher/SelectFileManagerWindow.xaml.cs
@@ -114,10 +114,11 @@ namespace Flow.Launcher
}
}
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD100:Avoid async void methods", Justification = "")]
private async void btnTips_Click(object sender, RoutedEventArgs e)
{
- string tipText = (string)Application.Current.Resources["fileManager_files_tips"];
- string url = "https://files.community/docs/contributing/updates";
+ var tipText = (string)Application.Current.Resources["fileManager_files_tips"];
+ var url = "https://files.community/docs/contributing/updates";
var textBlock = new TextBlock
{
@@ -128,7 +129,7 @@ namespace Flow.Launcher
textBlock.Inlines.Add(tipText);
- Hyperlink hyperlink = new Hyperlink
+ var hyperlink = new Hyperlink
{
NavigateUri = new Uri(url)
};
@@ -147,7 +148,7 @@ namespace Flow.Launcher
var tipsDialog = new ContentDialog()
{
- Owner = Window.GetWindow(sender as DependencyObject),
+ Owner = Window.GetWindow((DependencyObject)sender),
Title = (string)Application.Current.Resources["fileManager_files_btn"],
Content = textBlock,
PrimaryButtonText = (string)Application.Current.Resources["commonOK"],
From d23f88d2cb9cd71b0eb24d975ba7251a9dbfeb63 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 20 May 2025 21:44:17 +0800
Subject: [PATCH 1283/1697] Make sure vertically center
---
Flow.Launcher/SelectFileManagerWindow.xaml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/SelectFileManagerWindow.xaml b/Flow.Launcher/SelectFileManagerWindow.xaml
index 5e01a4a5f..563fbda53 100644
--- a/Flow.Launcher/SelectFileManagerWindow.xaml
+++ b/Flow.Launcher/SelectFileManagerWindow.xaml
@@ -76,11 +76,11 @@
-
+
From 5626ab71c730c906c91d69fc04bddb9c38def605 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 20 May 2025 21:57:49 +0800
Subject: [PATCH 1284/1697] Log information when failed to execute
---
Flow.Launcher/PublicAPIInstance.cs | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 6516388ac..a0614d90f 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -32,11 +32,14 @@ using Flow.Launcher.ViewModel;
using JetBrains.Annotations;
using Squirrel;
using Stopwatch = Flow.Launcher.Infrastructure.Stopwatch;
+using System.ComponentModel;
namespace Flow.Launcher
{
public class PublicAPIInstance : IPublicAPI, IRemovable
{
+ private static readonly string ClassName = nameof(PublicAPIInstance);
+
private readonly Settings _settings;
private readonly MainViewModel _mainVM;
@@ -353,9 +356,9 @@ namespace Flow.Launcher
explorer.Start();
}
- catch (System.ComponentModel.Win32Exception ex) when (ex.NativeErrorCode == 2)
+ catch (Win32Exception ex) when (ex.NativeErrorCode == 2)
{
- // File Manager not found
+ LogError(ClassName, "File Manager not found");
ShowMsgBox(
string.Format(GetTranslation("fileManagerNotFound"), ex.Message),
GetTranslation("fileManagerNotFoundTitle"),
@@ -365,7 +368,7 @@ namespace Flow.Launcher
}
catch (Exception ex)
{
- // Other exceptions
+ LogException(ClassName, "Failed to open folder", ex);
ShowMsgBox(
string.Format(GetTranslation("folderOpenError"), ex.Message),
GetTranslation("errorTitle"),
From 89fdd4815901518b53f4fa15e2feb6ba16102b71 Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Wed, 21 May 2025 07:37:14 +1000
Subject: [PATCH 1285/1697] 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 7d1635bab..1b72d9045 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -376,7 +376,7 @@
File Manager Path
Arg For Folder
Arg For File
- The path for the file manager '{0}' could not be found: '{1}' Do you want to continue?
+ The path for file manager '{0}' could not be found: '{1}' Do you want to continue?
File Manager Path Error
From 6e36b08cada0bdbcfc4d897d52aa57f2ec123ebc Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 21 May 2025 11:59:24 +0800
Subject: [PATCH 1286/1697] Use api functions instead
---
Flow.Launcher/SelectFileManagerWindow.xaml.cs | 20 +++++++------------
1 file changed, 7 insertions(+), 13 deletions(-)
diff --git a/Flow.Launcher/SelectFileManagerWindow.xaml.cs b/Flow.Launcher/SelectFileManagerWindow.xaml.cs
index 01517522d..62fbef43f 100644
--- a/Flow.Launcher/SelectFileManagerWindow.xaml.cs
+++ b/Flow.Launcher/SelectFileManagerWindow.xaml.cs
@@ -7,6 +7,7 @@ using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
+using System.Windows.Navigation;
using CommunityToolkit.Mvvm.ComponentModel;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.ViewModel;
@@ -33,6 +34,7 @@ namespace Flow.Launcher
public ObservableCollection CustomExplorers { get; set; }
public CustomExplorerViewModel CustomExplorer => CustomExplorers[SelectedCustomExplorerIndex];
+
public SelectFileManagerWindow(Settings settings)
{
_settings = settings;
@@ -46,13 +48,9 @@ namespace Flow.Launcher
Close();
}
- private void Hyperlink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e)
+ private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
{
- Process.Start(new ProcessStartInfo
- {
- FileName = e.Uri.AbsoluteUri,
- UseShellExecute = true
- });
+ App.API.OpenUrl(e.Uri.AbsoluteUri);
e.Handled = true;
}
@@ -62,9 +60,9 @@ namespace Flow.Launcher
if (!IsFileManagerValid(CustomExplorer.Path))
{
var result = App.API.ShowMsgBox(
- string.Format((string)Application.Current.FindResource("fileManagerPathNotFound"),
+ string.Format(App.API.GetTranslation("fileManagerPathNotFound"),
CustomExplorer.Name, CustomExplorer.Path),
- (string)Application.Current.FindResource("fileManagerPathError"),
+ App.API.GetTranslation("fileManagerPathError"),
MessageBoxButton.YesNo,
MessageBoxImage.Warning);
@@ -136,11 +134,7 @@ namespace Flow.Launcher
hyperlink.Inlines.Add(url);
hyperlink.RequestNavigate += (s, args) =>
{
- Process.Start(new ProcessStartInfo
- {
- FileName = args.Uri.AbsoluteUri,
- UseShellExecute = true
- });
+ App.API.OpenUrl(args.Uri.AbsoluteUri);
args.Handled = true;
};
From 152ad2f86ae27e28cd84a7c580cec00f37aa8e98 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 21 May 2025 12:04:47 +0800
Subject: [PATCH 1287/1697] Remove setter for observable collection & Add blank
line for code quality
---
Flow.Launcher/SelectBrowserWindow.xaml.cs | 4 +++-
Flow.Launcher/SelectFileManagerWindow.xaml.cs | 3 ++-
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/SelectBrowserWindow.xaml.cs b/Flow.Launcher/SelectBrowserWindow.xaml.cs
index bea5b4352..9e692ec72 100644
--- a/Flow.Launcher/SelectBrowserWindow.xaml.cs
+++ b/Flow.Launcher/SelectBrowserWindow.xaml.cs
@@ -23,9 +23,11 @@ namespace Flow.Launcher
OnPropertyChanged(nameof(CustomBrowser));
}
}
- public ObservableCollection CustomBrowsers { get; set; }
+
+ public ObservableCollection CustomBrowsers { get; }
public CustomBrowserViewModel CustomBrowser => CustomBrowsers[SelectedCustomBrowserIndex];
+
public SelectBrowserWindow(Settings settings)
{
_settings = settings;
diff --git a/Flow.Launcher/SelectFileManagerWindow.xaml.cs b/Flow.Launcher/SelectFileManagerWindow.xaml.cs
index 62fbef43f..e880f3ada 100644
--- a/Flow.Launcher/SelectFileManagerWindow.xaml.cs
+++ b/Flow.Launcher/SelectFileManagerWindow.xaml.cs
@@ -31,7 +31,8 @@ namespace Flow.Launcher
OnPropertyChanged(nameof(CustomExplorer));
}
}
- public ObservableCollection CustomExplorers { get; set; }
+
+ public ObservableCollection CustomExplorers { get; }
public CustomExplorerViewModel CustomExplorer => CustomExplorers[SelectedCustomExplorerIndex];
From 6ce2cf9cacfe44dd9bec379f7199b3519abf7128 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 21 May 2025 12:58:55 +0800
Subject: [PATCH 1288/1697] Refactor with MVVM
---
Flow.Launcher/App.xaml.cs | 4 +
Flow.Launcher/SelectBrowserWindow.xaml | 7 +-
Flow.Launcher/SelectBrowserWindow.xaml.cs | 57 ++----
Flow.Launcher/SelectFileManagerWindow.xaml | 10 +-
Flow.Launcher/SelectFileManagerWindow.xaml.cs | 166 ++----------------
.../SettingsPaneGeneralViewModel.cs | 4 +-
.../ViewModel/SelectBrowserViewModel.cs | 58 ++++++
.../ViewModel/SelectFileManagerViewModel.cs | 161 +++++++++++++++++
8 files changed, 264 insertions(+), 203 deletions(-)
create mode 100644 Flow.Launcher/ViewModel/SelectBrowserViewModel.cs
create mode 100644 Flow.Launcher/ViewModel/SelectFileManagerViewModel.cs
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 942e94470..969bb75bb 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -98,6 +98,10 @@ namespace Flow.Launcher
.AddTransient()
.AddTransient()
.AddTransient()
+ // Use transient instance for dialog view models because
+ // settings will change and we need to recreate them
+ .AddTransient()
+ .AddTransient()
).Build();
Ioc.Default.ConfigureServices(host.Services);
}
diff --git a/Flow.Launcher/SelectBrowserWindow.xaml b/Flow.Launcher/SelectBrowserWindow.xaml
index 4a0928dc2..d51d597b7 100644
--- a/Flow.Launcher/SelectBrowserWindow.xaml
+++ b/Flow.Launcher/SelectBrowserWindow.xaml
@@ -6,10 +6,11 @@
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"
Title="{DynamicResource defaultBrowserTitle}"
Width="550"
+ d:DataContext="{d:DesignInstance vm:SelectBrowserViewModel}"
Background="{DynamicResource PopuBGColor}"
- DataContext="{Binding RelativeSource={RelativeSource Self}}"
Foreground="{DynamicResource PopupTextColor}"
ResizeMode="NoResize"
SizeToContent="Height"
@@ -97,11 +98,11 @@
diff --git a/Flow.Launcher/SelectBrowserWindow.xaml.cs b/Flow.Launcher/SelectBrowserWindow.xaml.cs
index 9e692ec72..2d200fe98 100644
--- a/Flow.Launcher/SelectBrowserWindow.xaml.cs
+++ b/Flow.Launcher/SelectBrowserWindow.xaml.cs
@@ -1,38 +1,18 @@
-using System.Collections.ObjectModel;
-using System.Linq;
-using System.Windows;
+using System.Windows;
using System.Windows.Controls;
-using CommunityToolkit.Mvvm.ComponentModel;
-using Flow.Launcher.Infrastructure.UserSettings;
+using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.ViewModel;
namespace Flow.Launcher
{
- [INotifyPropertyChanged]
public partial class SelectBrowserWindow : Window
{
- private readonly Settings _settings;
+ private readonly SelectBrowserViewModel _viewModel;
- private int selectedCustomBrowserIndex;
-
- public int SelectedCustomBrowserIndex
+ public SelectBrowserWindow()
{
- get => selectedCustomBrowserIndex;
- set
- {
- selectedCustomBrowserIndex = value;
- OnPropertyChanged(nameof(CustomBrowser));
- }
- }
-
- public ObservableCollection CustomBrowsers { get; }
-
- public CustomBrowserViewModel CustomBrowser => CustomBrowsers[SelectedCustomBrowserIndex];
-
- public SelectBrowserWindow(Settings settings)
- {
- _settings = settings;
- CustomBrowsers = new ObservableCollection(_settings.CustomBrowserList.Select(x => x.Copy()));
- SelectedCustomBrowserIndex = _settings.CustomBrowserIndex;
+ _viewModel = Ioc.Default.GetRequiredService();
+ DataContext = _viewModel;
InitializeComponent();
}
@@ -43,32 +23,19 @@ namespace Flow.Launcher
private void btnDone_Click(object sender, RoutedEventArgs e)
{
- _settings.CustomBrowserList = CustomBrowsers.ToList();
- _settings.CustomBrowserIndex = SelectedCustomBrowserIndex;
- Close();
- }
-
- private void btnAdd_Click(object sender, RoutedEventArgs e)
- {
- CustomBrowsers.Add(new()
+ if (_viewModel.SaveSettings())
{
- Name = "New Profile"
- });
- SelectedCustomBrowserIndex = CustomBrowsers.Count - 1;
- }
-
- private void btnDelete_Click(object sender, RoutedEventArgs e)
- {
- CustomBrowsers.RemoveAt(SelectedCustomBrowserIndex--);
+ Close();
+ }
}
private void btnBrowseFile_Click(object sender, RoutedEventArgs e)
{
- Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
+ var dlg = new Microsoft.Win32.OpenFileDialog();
var result = dlg.ShowDialog();
if (result == true)
{
- TextBox path = (TextBox)(((FrameworkElement)sender).Parent as FrameworkElement).FindName("PathTextBox");
+ var path = (TextBox)(((FrameworkElement)sender).Parent as FrameworkElement).FindName("PathTextBox");
path.Text = dlg.FileName;
path.Focus();
((Button)sender).Focus();
diff --git a/Flow.Launcher/SelectFileManagerWindow.xaml b/Flow.Launcher/SelectFileManagerWindow.xaml
index 563fbda53..ecd4a282a 100644
--- a/Flow.Launcher/SelectFileManagerWindow.xaml
+++ b/Flow.Launcher/SelectFileManagerWindow.xaml
@@ -6,10 +6,11 @@
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"
Title="{DynamicResource fileManagerWindow}"
Width="600"
+ d:DataContext="{d:DesignInstance vm:SelectFileManagerViewModel}"
Background="{DynamicResource PopuBGColor}"
- DataContext="{Binding RelativeSource={RelativeSource Self}}"
Foreground="{DynamicResource PopupTextColor}"
ResizeMode="NoResize"
SizeToContent="Height"
@@ -78,7 +79,8 @@
x:Name="btnTips"
Margin="0 7 0 7"
HorizontalAlignment="Left"
- Click="btnTips_Click"
+ Command="{Binding OpenFilesTipsCommand}"
+ CommandParameter="{Binding RelativeSource={RelativeSource Self}}"
Content="{DynamicResource fileManager_files_btn}" />
@@ -115,11 +117,11 @@
diff --git a/Flow.Launcher/SelectFileManagerWindow.xaml.cs b/Flow.Launcher/SelectFileManagerWindow.xaml.cs
index e880f3ada..0809ccb30 100644
--- a/Flow.Launcher/SelectFileManagerWindow.xaml.cs
+++ b/Flow.Launcher/SelectFileManagerWindow.xaml.cs
@@ -1,46 +1,19 @@
-using System;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using System.Windows;
+using System.Windows;
using System.Windows.Controls;
-using System.Windows.Documents;
using System.Windows.Navigation;
-using CommunityToolkit.Mvvm.ComponentModel;
-using Flow.Launcher.Infrastructure.UserSettings;
+using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.ViewModel;
-using ModernWpf.Controls;
namespace Flow.Launcher
{
- [INotifyPropertyChanged]
public partial class SelectFileManagerWindow : Window
{
- private readonly Settings _settings;
+ private readonly SelectFileManagerViewModel _viewModel;
- private int selectedCustomExplorerIndex;
-
- public int SelectedCustomExplorerIndex
+ public SelectFileManagerWindow()
{
- get => selectedCustomExplorerIndex;
- set
- {
- selectedCustomExplorerIndex = value;
- OnPropertyChanged(nameof(CustomExplorer));
- }
- }
-
- public ObservableCollection CustomExplorers { get; }
-
- public CustomExplorerViewModel CustomExplorer => CustomExplorers[SelectedCustomExplorerIndex];
-
- public SelectFileManagerWindow(Settings settings)
- {
- _settings = settings;
- CustomExplorers = new ObservableCollection(_settings.CustomExplorerList.Select(x => x.Copy()));
- SelectedCustomExplorerIndex = _settings.CustomExplorerIndex;
+ _viewModel = Ioc.Default.GetRequiredService();
+ DataContext = _viewModel;
InitializeComponent();
}
@@ -48,133 +21,28 @@ namespace Flow.Launcher
{
Close();
}
-
+
+ private void btnDone_Click(object sender, RoutedEventArgs e)
+ {
+ if (_viewModel.SaveSettings())
+ {
+ Close();
+ }
+ }
+
private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
{
App.API.OpenUrl(e.Uri.AbsoluteUri);
e.Handled = true;
}
- private void btnDone_Click(object sender, RoutedEventArgs e)
- {
- // Check if the selected file manager path is valid
- if (!IsFileManagerValid(CustomExplorer.Path))
- {
- var result = App.API.ShowMsgBox(
- string.Format(App.API.GetTranslation("fileManagerPathNotFound"),
- CustomExplorer.Name, CustomExplorer.Path),
- App.API.GetTranslation("fileManagerPathError"),
- MessageBoxButton.YesNo,
- MessageBoxImage.Warning);
-
- if (result == MessageBoxResult.No)
- {
- return;
- }
- }
-
- _settings.CustomExplorerList = CustomExplorers.ToList();
- _settings.CustomExplorerIndex = SelectedCustomExplorerIndex;
- Close();
- }
-
- private bool IsFileManagerValid(string path)
- {
- if (string.Equals(path, "explorer", StringComparison.OrdinalIgnoreCase))
- return true;
-
- if (Path.IsPathRooted(path))
- {
- return File.Exists(path);
- }
-
- try
- {
- var process = new Process
- {
- StartInfo = new ProcessStartInfo
- {
- FileName = "where",
- Arguments = path,
- RedirectStandardOutput = true,
- UseShellExecute = false,
- CreateNoWindow = true
- }
- };
- process.Start();
- string output = process.StandardOutput.ReadToEnd();
- process.WaitForExit();
-
- return !string.IsNullOrEmpty(output);
- }
- catch
- {
- return false;
- }
- }
-
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD100:Avoid async void methods", Justification = "")]
- private async void btnTips_Click(object sender, RoutedEventArgs e)
- {
- var tipText = (string)Application.Current.Resources["fileManager_files_tips"];
- var url = "https://files.community/docs/contributing/updates";
-
- var textBlock = new TextBlock
- {
- FontSize = 14,
- TextWrapping = TextWrapping.Wrap,
- Margin = new Thickness(0, 0, 0, 0)
- };
-
- textBlock.Inlines.Add(tipText);
-
- var hyperlink = new Hyperlink
- {
- NavigateUri = new Uri(url)
- };
- hyperlink.Inlines.Add(url);
- hyperlink.RequestNavigate += (s, args) =>
- {
- App.API.OpenUrl(args.Uri.AbsoluteUri);
- args.Handled = true;
- };
-
- textBlock.Inlines.Add(hyperlink);
-
- var tipsDialog = new ContentDialog()
- {
- Owner = Window.GetWindow((DependencyObject)sender),
- Title = (string)Application.Current.Resources["fileManager_files_btn"],
- Content = textBlock,
- PrimaryButtonText = (string)Application.Current.Resources["commonOK"],
- CornerRadius = new CornerRadius(8),
- Style = (Style)Application.Current.Resources["ContentDialog"]
- };
-
- await tipsDialog.ShowAsync();
- }
-
- private void btnAdd_Click(object sender, RoutedEventArgs e)
- {
- CustomExplorers.Add(new()
- {
- Name = "New Profile"
- });
- SelectedCustomExplorerIndex = CustomExplorers.Count - 1;
- }
-
- private void btnDelete_Click(object sender, RoutedEventArgs e)
- {
- CustomExplorers.RemoveAt(SelectedCustomExplorerIndex--);
- }
-
private void btnBrowseFile_Click(object sender, RoutedEventArgs e)
{
- Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
+ var dlg = new Microsoft.Win32.OpenFileDialog();
var result = dlg.ShowDialog();
if (result == true)
{
- TextBox path = (TextBox)(((FrameworkElement)sender).Parent as FrameworkElement).FindName("PathTextBox");
+ var path = (TextBox)(((FrameworkElement)sender).Parent as FrameworkElement).FindName("PathTextBox");
path.Text = dlg.FileName;
path.Focus();
((Button)sender).Focus();
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
index 840269b03..eac40099b 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -335,14 +335,14 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
[RelayCommand]
private void SelectFileManager()
{
- var fileManagerChangeWindow = new SelectFileManagerWindow(Settings);
+ var fileManagerChangeWindow = new SelectFileManagerWindow();
fileManagerChangeWindow.ShowDialog();
}
[RelayCommand]
private void SelectBrowser()
{
- var browserWindow = new SelectBrowserWindow(Settings);
+ var browserWindow = new SelectBrowserWindow();
browserWindow.ShowDialog();
}
}
diff --git a/Flow.Launcher/ViewModel/SelectBrowserViewModel.cs b/Flow.Launcher/ViewModel/SelectBrowserViewModel.cs
new file mode 100644
index 000000000..537263fcf
--- /dev/null
+++ b/Flow.Launcher/ViewModel/SelectBrowserViewModel.cs
@@ -0,0 +1,58 @@
+using System.Collections.ObjectModel;
+using System.Linq;
+using CommunityToolkit.Mvvm.Input;
+using Flow.Launcher.Infrastructure.UserSettings;
+using Flow.Launcher.Plugin;
+
+namespace Flow.Launcher.ViewModel;
+
+public partial class SelectBrowserViewModel : BaseModel
+{
+ private readonly Settings _settings;
+
+ private int selectedCustomBrowserIndex;
+
+ public int SelectedCustomBrowserIndex
+ {
+ get => selectedCustomBrowserIndex;
+ set
+ {
+ selectedCustomBrowserIndex = value;
+ OnPropertyChanged(nameof(CustomBrowser));
+ }
+ }
+
+ public ObservableCollection CustomBrowsers { get; }
+
+ public CustomBrowserViewModel CustomBrowser => CustomBrowsers[SelectedCustomBrowserIndex];
+
+ public SelectBrowserViewModel(Settings settings)
+ {
+ _settings = settings;
+ CustomBrowsers = new ObservableCollection(_settings.CustomBrowserList.Select(x => x.Copy()));
+ SelectedCustomBrowserIndex = _settings.CustomBrowserIndex;
+ }
+
+ public bool SaveSettings()
+ {
+ _settings.CustomBrowserList = CustomBrowsers.ToList();
+ _settings.CustomBrowserIndex = SelectedCustomBrowserIndex;
+ return true;
+ }
+
+ [RelayCommand]
+ private void Add()
+ {
+ CustomBrowsers.Add(new()
+ {
+ Name = "New Profile"
+ });
+ SelectedCustomBrowserIndex = CustomBrowsers.Count - 1;
+ }
+
+ [RelayCommand]
+ private void Delete()
+ {
+ CustomBrowsers.RemoveAt(SelectedCustomBrowserIndex--);
+ }
+}
diff --git a/Flow.Launcher/ViewModel/SelectFileManagerViewModel.cs b/Flow.Launcher/ViewModel/SelectFileManagerViewModel.cs
new file mode 100644
index 000000000..2b5729f05
--- /dev/null
+++ b/Flow.Launcher/ViewModel/SelectFileManagerViewModel.cs
@@ -0,0 +1,161 @@
+using System;
+using System.Collections.ObjectModel;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using CommunityToolkit.Mvvm.Input;
+using Flow.Launcher.Infrastructure.UserSettings;
+using Flow.Launcher.Plugin;
+using ModernWpf.Controls;
+
+namespace Flow.Launcher.ViewModel;
+
+public partial class SelectFileManagerViewModel : BaseModel
+{
+ private readonly Settings _settings;
+
+ private int selectedCustomExplorerIndex;
+
+ public int SelectedCustomExplorerIndex
+ {
+ get => selectedCustomExplorerIndex;
+ set
+ {
+ if (selectedCustomExplorerIndex != value)
+ {
+ selectedCustomExplorerIndex = value;
+ OnPropertyChanged(nameof(CustomExplorer));
+ }
+ }
+ }
+
+ public ObservableCollection CustomExplorers { get; }
+
+ public CustomExplorerViewModel CustomExplorer => CustomExplorers[SelectedCustomExplorerIndex];
+
+ public SelectFileManagerViewModel(Settings settings)
+ {
+ _settings = settings;
+ CustomExplorers = new ObservableCollection(_settings.CustomExplorerList.Select(x => x.Copy()));
+ SelectedCustomExplorerIndex = _settings.CustomExplorerIndex;
+ }
+
+ public bool SaveSettings()
+ {
+ // Check if the selected file manager path is valid
+ if (!IsFileManagerValid(CustomExplorer.Path))
+ {
+ var result = App.API.ShowMsgBox(
+ string.Format(App.API.GetTranslation("fileManagerPathNotFound"),
+ CustomExplorer.Name, CustomExplorer.Path),
+ App.API.GetTranslation("fileManagerPathError"),
+ MessageBoxButton.YesNo,
+ MessageBoxImage.Warning);
+
+ if (result == MessageBoxResult.No)
+ {
+ return false;
+ }
+ }
+
+ _settings.CustomExplorerList = CustomExplorers.ToList();
+ _settings.CustomExplorerIndex = SelectedCustomExplorerIndex;
+ return true;
+ }
+
+ private static bool IsFileManagerValid(string path)
+ {
+ if (string.Equals(path, "explorer", StringComparison.OrdinalIgnoreCase))
+ return true;
+
+ if (Path.IsPathRooted(path))
+ {
+ return File.Exists(path);
+ }
+
+ try
+ {
+ var process = new Process
+ {
+ StartInfo = new ProcessStartInfo
+ {
+ FileName = "where",
+ Arguments = path,
+ RedirectStandardOutput = true,
+ UseShellExecute = false,
+ CreateNoWindow = true
+ }
+ };
+ process.Start();
+ string output = process.StandardOutput.ReadToEnd();
+ process.WaitForExit();
+
+ return !string.IsNullOrEmpty(output);
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ [RelayCommand]
+ private async Task OpenFilesTipsAsync(Button button)
+ {
+ var tipText = App.API.GetTranslation("fileManager_files_tips");
+ var url = "https://files.community/docs/contributing/updates";
+
+ var textBlock = new TextBlock
+ {
+ FontSize = 14,
+ TextWrapping = TextWrapping.Wrap,
+ Margin = new Thickness(0, 0, 0, 0)
+ };
+
+ textBlock.Inlines.Add(tipText);
+
+ var hyperlink = new Hyperlink
+ {
+ NavigateUri = new Uri(url)
+ };
+ hyperlink.Inlines.Add(url);
+ hyperlink.RequestNavigate += (s, args) =>
+ {
+ App.API.OpenUrl(args.Uri.AbsoluteUri);
+ args.Handled = true;
+ };
+
+ textBlock.Inlines.Add(hyperlink);
+
+ var tipsDialog = new ContentDialog()
+ {
+ Owner = Window.GetWindow(button),
+ Title = (string)Application.Current.Resources["fileManager_files_btn"],
+ Content = textBlock,
+ PrimaryButtonText = (string)Application.Current.Resources["commonOK"],
+ CornerRadius = new CornerRadius(8),
+ Style = (Style)Application.Current.Resources["ContentDialog"]
+ };
+
+ await tipsDialog.ShowAsync();
+ }
+
+ [RelayCommand]
+ private void Add()
+ {
+ CustomExplorers.Add(new()
+ {
+ Name = "New Profile"
+ });
+ SelectedCustomExplorerIndex = CustomExplorers.Count - 1;
+ }
+
+ [RelayCommand]
+ private void Delete()
+ {
+ CustomExplorers.RemoveAt(SelectedCustomExplorerIndex--);
+ }
+}
From f7f52e269a8f0aa7883169c82425fd9738a8dc7f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 21 May 2025 14:31:09 +0800
Subject: [PATCH 1289/1697] Set culture info before creating application
---
.../Resource/Internationalization.cs | 34 ++++++----
.../UserSettings/Settings.cs | 13 +++-
Flow.Launcher/App.xaml.cs | 62 ++++++++++++-------
3 files changed, 71 insertions(+), 38 deletions(-)
diff --git a/Flow.Launcher.Core/Resource/Internationalization.cs b/Flow.Launcher.Core/Resource/Internationalization.cs
index b32b09e8f..3329e3a96 100644
--- a/Flow.Launcher.Core/Resource/Internationalization.cs
+++ b/Flow.Launcher.Core/Resource/Internationalization.cs
@@ -1,16 +1,17 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
+using System.Threading;
+using System.Threading.Tasks;
using System.Windows;
+using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Core.Plugin;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
-using System.Globalization;
-using System.Threading.Tasks;
-using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher.Core.Resource
{
@@ -29,13 +30,12 @@ namespace Flow.Launcher.Core.Resource
private readonly Settings _settings;
private readonly List _languageDirectories = new();
private readonly List _oldResources = new();
- private readonly string SystemLanguageCode;
+ private static string SystemLanguageCode;
public Internationalization(Settings settings)
{
_settings = settings;
AddFlowLauncherLanguageDirectory();
- SystemLanguageCode = GetSystemLanguageCodeAtStartup();
}
private void AddFlowLauncherLanguageDirectory()
@@ -44,7 +44,7 @@ namespace Flow.Launcher.Core.Resource
_languageDirectories.Add(directory);
}
- private static string GetSystemLanguageCodeAtStartup()
+ public static void InitSystemLanguageCode()
{
var availableLanguages = AvailableLanguages.GetAvailableLanguages();
@@ -65,11 +65,11 @@ namespace Flow.Launcher.Core.Resource
string.Equals(languageCode, threeLetterCode, StringComparison.OrdinalIgnoreCase) ||
string.Equals(languageCode, fullName, StringComparison.OrdinalIgnoreCase))
{
- return languageCode;
+ SystemLanguageCode = languageCode;
}
}
- return DefaultLanguageCode;
+ SystemLanguageCode = DefaultLanguageCode;
}
private void AddPluginLanguageDirectories()
@@ -173,15 +173,25 @@ namespace Flow.Launcher.Core.Resource
LoadLanguage(language);
}
- // Culture of main thread
- // Use CreateSpecificCulture to preserve possible user-override settings in Windows, if Flow's language culture is the same as Windows's
- CultureInfo.CurrentCulture = CultureInfo.CreateSpecificCulture(language.LanguageCode);
- CultureInfo.CurrentUICulture = CultureInfo.CurrentCulture;
+ // Change culture info
+ ChangeCultureInfo(language.LanguageCode);
// Raise event for plugins after culture is set
await Task.Run(UpdatePluginMetadataTranslations);
}
+ public static void ChangeCultureInfo(string languageCode)
+ {
+ // Culture of main thread
+ // Use CreateSpecificCulture to preserve possible user-override settings in Windows, if Flow's language culture is the same as Windows's
+ var currentCulture = CultureInfo.CreateSpecificCulture(languageCode);
+ CultureInfo.CurrentCulture = currentCulture;
+ CultureInfo.CurrentUICulture = currentCulture;
+ var thread = Thread.CurrentThread;
+ thread.CurrentCulture = currentCulture;
+ thread.CurrentUICulture = currentCulture;
+ }
+
public bool PromptShouldUsePinyin(string languageCodeToSet)
{
var languageToSet = GetLanguageByLanguageCode(languageCodeToSet);
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index 027eb3f92..7933d08ea 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -25,7 +25,13 @@ namespace Flow.Launcher.Infrastructure.UserSettings
public void Initialize()
{
+ // Initialize dependency injection instances after Ioc.Default is created
_stringMatcher = Ioc.Default.GetRequiredService();
+
+ // Initialize application resources after application is created
+ var settingWindowFont = new FontFamily(SettingWindowFont);
+ Application.Current.Resources["SettingWindowFont"] = settingWindowFont;
+ Application.Current.Resources["ContentControlThemeFontFamily"] = settingWindowFont;
}
public void Save()
@@ -114,8 +120,11 @@ namespace Flow.Launcher.Infrastructure.UserSettings
{
_settingWindowFont = value;
OnPropertyChanged();
- Application.Current.Resources["SettingWindowFont"] = new FontFamily(value);
- Application.Current.Resources["ContentControlThemeFontFamily"] = new FontFamily(value);
+ if (Application.Current != null)
+ {
+ Application.Current.Resources["SettingWindowFont"] = new FontFamily(value);
+ Application.Current.Resources["ContentControlThemeFontFamily"] = new FontFamily(value);
+ }
}
}
}
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 942e94470..fd64ad3e0 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -41,9 +41,9 @@ namespace Flow.Launcher
private static readonly string ClassName = nameof(App);
private static bool _disposed;
+ private static Settings _settings;
private static MainWindow _mainWindow;
private readonly MainViewModel _mainVM;
- private readonly Settings _settings;
// To prevent two disposals running at the same time.
private static readonly object _disposingLock = new();
@@ -55,19 +55,7 @@ namespace Flow.Launcher
public App()
{
// Initialize settings
- try
- {
- var storage = new FlowLauncherJsonStorage();
- _settings = storage.Load();
- _settings.SetStorage(storage);
- _settings.WMPInstalled = WindowsMediaPlayerHelper.IsWindowsMediaPlayerInstalled();
- }
- catch (Exception e)
- {
- ShowErrorMsgBoxAndFailFast("Cannot load setting storage, please check local data directory", e);
- return;
- }
-
+ _settings.WMPInstalled = WindowsMediaPlayerHelper.IsWindowsMediaPlayerInstalled();
// Configure the dependency injection container
try
{
@@ -119,16 +107,6 @@ namespace Flow.Launcher
ShowErrorMsgBoxAndFailFast("Cannot initialize api and settings, please open new issue in Flow.Launcher", e);
return;
}
-
- // Local function
- static void ShowErrorMsgBoxAndFailFast(string message, Exception e)
- {
- // Firstly show users the message
- MessageBox.Show(e.ToString(), message, MessageBoxButton.OK, MessageBoxImage.Error);
-
- // Flow cannot construct its App instance, so ensure Flow crashes w/ the exception info.
- Environment.FailFast(message, e);
- }
}
#endregion
@@ -138,6 +116,29 @@ namespace Flow.Launcher
[STAThread]
public static void Main()
{
+ // Initialize settings so that we can get language code
+ try
+ {
+ var storage = new FlowLauncherJsonStorage();
+ _settings = storage.Load();
+ _settings.SetStorage(storage);
+ }
+ catch (Exception e)
+ {
+ ShowErrorMsgBoxAndFailFast("Cannot load setting storage, please check local data directory", e);
+ return;
+ }
+
+ // Initialize system language before changing culture info
+ Internationalization.InitSystemLanguageCode();
+
+ // Change culture info before application creation to localize WinForm windows
+ if (_settings.Language != Constant.SystemLanguageCode)
+ {
+ Internationalization.ChangeCultureInfo(_settings.Language);
+ }
+
+ // Start the application as a single instance
if (SingleInstance.InitializeAsFirstInstance())
{
using var application = new App();
@@ -148,6 +149,19 @@ namespace Flow.Launcher
#endregion
+ #region Fail Fast
+
+ private static void ShowErrorMsgBoxAndFailFast(string message, Exception e)
+ {
+ // Firstly show users the message
+ MessageBox.Show(e.ToString(), message, MessageBoxButton.OK, MessageBoxImage.Error);
+
+ // Flow cannot construct its App instance, so ensure Flow crashes w/ the exception info.
+ Environment.FailFast(message, e);
+ }
+
+ #endregion
+
#region App Events
#pragma warning disable VSTHRD100 // Avoid async void methods
From b0997449c17117214a246c537b2472db5fb88596 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 21 May 2025 14:38:15 +0800
Subject: [PATCH 1290/1697] Handle CultureNotFoundException
---
Flow.Launcher.Core/Resource/Internationalization.cs | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher.Core/Resource/Internationalization.cs b/Flow.Launcher.Core/Resource/Internationalization.cs
index 3329e3a96..24edc5ed8 100644
--- a/Flow.Launcher.Core/Resource/Internationalization.cs
+++ b/Flow.Launcher.Core/Resource/Internationalization.cs
@@ -184,7 +184,15 @@ namespace Flow.Launcher.Core.Resource
{
// Culture of main thread
// Use CreateSpecificCulture to preserve possible user-override settings in Windows, if Flow's language culture is the same as Windows's
- var currentCulture = CultureInfo.CreateSpecificCulture(languageCode);
+ CultureInfo currentCulture;
+ try
+ {
+ currentCulture = CultureInfo.CreateSpecificCulture(languageCode);
+ }
+ catch (CultureNotFoundException)
+ {
+ currentCulture = CultureInfo.CreateSpecificCulture(SystemLanguageCode);
+ }
CultureInfo.CurrentCulture = currentCulture;
CultureInfo.CurrentUICulture = currentCulture;
var thread = Thread.CurrentThread;
From 5578daaa3eeb0875c7d301a5e7d27bafbad1b6d2 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 21 May 2025 18:25:33 +0800
Subject: [PATCH 1291/1697] Remove files tip button
---
Flow.Launcher/Languages/en.xaml | 2 -
Flow.Launcher/SelectFileManagerWindow.xaml | 19 +++------
.../ViewModel/SelectFileManagerViewModel.cs | 41 -------------------
3 files changed, 5 insertions(+), 57 deletions(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 1b72d9045..c58c63a5e 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -366,9 +366,7 @@
Select File Manager
- Do you use Files?
Learn more
- Depending on the version, Files may use either "Files" or "Files-stable" as its path. (This can vary depending on which version you're using.) For more details, see:
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
diff --git a/Flow.Launcher/SelectFileManagerWindow.xaml b/Flow.Launcher/SelectFileManagerWindow.xaml
index ecd4a282a..b3b219d1c 100644
--- a/Flow.Launcher/SelectFileManagerWindow.xaml
+++ b/Flow.Launcher/SelectFileManagerWindow.xaml
@@ -74,20 +74,11 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
- {
- App.API.OpenUrl(args.Uri.AbsoluteUri);
- args.Handled = true;
- };
-
- textBlock.Inlines.Add(hyperlink);
-
- var tipsDialog = new ContentDialog()
- {
- Owner = Window.GetWindow(button),
- Title = (string)Application.Current.Resources["fileManager_files_btn"],
- Content = textBlock,
- PrimaryButtonText = (string)Application.Current.Resources["commonOK"],
- CornerRadius = new CornerRadius(8),
- Style = (Style)Application.Current.Resources["ContentDialog"]
- };
-
- await tipsDialog.ShowAsync();
- }
-
[RelayCommand]
private void Add()
{
From 45b81811f7d4b11540a3ad24250970443da61a7d Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 21 May 2025 18:37:52 +0800
Subject: [PATCH 1292/1697] Fix potential issue with index boundary in Delete
command
---
Flow.Launcher/ViewModel/SelectBrowserViewModel.cs | 7 ++++++-
Flow.Launcher/ViewModel/SelectFileManagerViewModel.cs | 11 ++++++-----
2 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/Flow.Launcher/ViewModel/SelectBrowserViewModel.cs b/Flow.Launcher/ViewModel/SelectBrowserViewModel.cs
index 537263fcf..12f43d752 100644
--- a/Flow.Launcher/ViewModel/SelectBrowserViewModel.cs
+++ b/Flow.Launcher/ViewModel/SelectBrowserViewModel.cs
@@ -53,6 +53,11 @@ public partial class SelectBrowserViewModel : BaseModel
[RelayCommand]
private void Delete()
{
- CustomBrowsers.RemoveAt(SelectedCustomBrowserIndex--);
+ var currentIndex = SelectedCustomBrowserIndex;
+ if (currentIndex >= 0 && currentIndex < CustomBrowsers.Count)
+ {
+ CustomBrowsers.RemoveAt(currentIndex);
+ SelectedCustomBrowserIndex = currentIndex > 0 ? currentIndex - 1 : 0;
+ }
}
}
diff --git a/Flow.Launcher/ViewModel/SelectFileManagerViewModel.cs b/Flow.Launcher/ViewModel/SelectFileManagerViewModel.cs
index ee7da9e0f..253f74b47 100644
--- a/Flow.Launcher/ViewModel/SelectFileManagerViewModel.cs
+++ b/Flow.Launcher/ViewModel/SelectFileManagerViewModel.cs
@@ -3,14 +3,10 @@ using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
-using System.Threading.Tasks;
using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
-using ModernWpf.Controls;
namespace Flow.Launcher.ViewModel;
@@ -115,6 +111,11 @@ public partial class SelectFileManagerViewModel : BaseModel
[RelayCommand]
private void Delete()
{
- CustomExplorers.RemoveAt(SelectedCustomExplorerIndex--);
+ var currentIndex = SelectedCustomExplorerIndex;
+ if (currentIndex >= 0 && currentIndex < CustomExplorers.Count)
+ {
+ CustomExplorers.RemoveAt(currentIndex);
+ SelectedCustomExplorerIndex = currentIndex > 0 ? currentIndex - 1 : 0;
+ }
}
}
From 9a692a894d6b9f745e5090eb28fd6bc3daf7b2d1 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 21 May 2025 18:45:35 +0800
Subject: [PATCH 1293/1697] Add whitespace
---
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 c58c63a5e..627d111d0 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -468,7 +468,7 @@
File Manager Error
- The specified file manager could not be found. Please check the Custom File Manager setting under Settings >General.
+ The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General.
Error
An error occurred while opening the folder. {0}
From 07f77f00774b4f58244e9077f27327549a8eed94 Mon Sep 17 00:00:00 2001
From: Jeremy
Date: Wed, 21 May 2025 21:30:47 +1000
Subject: [PATCH 1294/1697] move calls to viewmodel
---
Flow.Launcher/SelectFileManagerWindow.xaml.cs | 10 +++++-----
.../ViewModel/SelectFileManagerViewModel.cs | 17 +++++++++++++++++
2 files changed, 22 insertions(+), 5 deletions(-)
diff --git a/Flow.Launcher/SelectFileManagerWindow.xaml.cs b/Flow.Launcher/SelectFileManagerWindow.xaml.cs
index 0809ccb30..d9c672aff 100644
--- a/Flow.Launcher/SelectFileManagerWindow.xaml.cs
+++ b/Flow.Launcher/SelectFileManagerWindow.xaml.cs
@@ -32,18 +32,18 @@ namespace Flow.Launcher
private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
{
- App.API.OpenUrl(e.Uri.AbsoluteUri);
+ _viewModel.OpenUrl(e.Uri.AbsoluteUri);
e.Handled = true;
}
private void btnBrowseFile_Click(object sender, RoutedEventArgs e)
{
- var dlg = new Microsoft.Win32.OpenFileDialog();
- var result = dlg.ShowDialog();
- if (result == true)
+ var selectedFilePath = _viewModel.SelectFile();
+
+ if (!string.IsNullOrEmpty(selectedFilePath))
{
var path = (TextBox)(((FrameworkElement)sender).Parent as FrameworkElement).FindName("PathTextBox");
- path.Text = dlg.FileName;
+ path.Text = selectedFilePath;
path.Focus();
((Button)sender).Focus();
}
diff --git a/Flow.Launcher/ViewModel/SelectFileManagerViewModel.cs b/Flow.Launcher/ViewModel/SelectFileManagerViewModel.cs
index 253f74b47..a72eff280 100644
--- a/Flow.Launcher/ViewModel/SelectFileManagerViewModel.cs
+++ b/Flow.Launcher/ViewModel/SelectFileManagerViewModel.cs
@@ -98,6 +98,23 @@ public partial class SelectFileManagerViewModel : BaseModel
}
}
+ internal void OpenUrl(string absoluteUri)
+ {
+ App.API.OpenUrl(absoluteUri);
+ }
+
+ internal string SelectFile()
+ {
+ var dlg = new Microsoft.Win32.OpenFileDialog();
+ var result = dlg.ShowDialog();
+ if (result == true)
+ {
+ return dlg.FileName;
+ }
+
+ return string.Empty;
+ }
+
[RelayCommand]
private void Add()
{
From e2d50cd80be4ad225fa29fff3b33b5a56ca7b0e1 Mon Sep 17 00:00:00 2001
From: Jeremy
Date: Wed, 21 May 2025 21:31:03 +1000
Subject: [PATCH 1295/1697] update wording
---
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 627d111d0..f233a30d5 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -374,7 +374,7 @@
File Manager Path
Arg For Folder
Arg For File
- The path for file manager '{0}' could not be found: '{1}' Do you want to continue?
+ The file manager '{0}' could not be located at '{1}'. Would you like to continue?
File Manager Path Error
From 41b9cd496ba9b5d99637a3f4ead74ebb73ac7f5a Mon Sep 17 00:00:00 2001
From: Jeremy
Date: Wed, 21 May 2025 21:39:46 +1000
Subject: [PATCH 1296/1697] move code to viewmodel
---
Flow.Launcher/SelectBrowserWindow.xaml.cs | 8 ++++----
Flow.Launcher/ViewModel/SelectBrowserViewModel.cs | 11 +++++++++++
Flow.Launcher/ViewModel/SelectFileManagerViewModel.cs | 2 --
3 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/Flow.Launcher/SelectBrowserWindow.xaml.cs b/Flow.Launcher/SelectBrowserWindow.xaml.cs
index 2d200fe98..565b4cbc3 100644
--- a/Flow.Launcher/SelectBrowserWindow.xaml.cs
+++ b/Flow.Launcher/SelectBrowserWindow.xaml.cs
@@ -31,12 +31,12 @@ namespace Flow.Launcher
private void btnBrowseFile_Click(object sender, RoutedEventArgs e)
{
- var dlg = new Microsoft.Win32.OpenFileDialog();
- var result = dlg.ShowDialog();
- if (result == true)
+ var selectedFilePath = _viewModel.SelectFile();
+
+ if (!string.IsNullOrEmpty(selectedFilePath))
{
var path = (TextBox)(((FrameworkElement)sender).Parent as FrameworkElement).FindName("PathTextBox");
- path.Text = dlg.FileName;
+ path.Text = selectedFilePath;
path.Focus();
((Button)sender).Focus();
}
diff --git a/Flow.Launcher/ViewModel/SelectBrowserViewModel.cs b/Flow.Launcher/ViewModel/SelectBrowserViewModel.cs
index 12f43d752..1eee6dba5 100644
--- a/Flow.Launcher/ViewModel/SelectBrowserViewModel.cs
+++ b/Flow.Launcher/ViewModel/SelectBrowserViewModel.cs
@@ -1,5 +1,6 @@
using System.Collections.ObjectModel;
using System.Linq;
+using System.Windows;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
@@ -40,6 +41,16 @@ public partial class SelectBrowserViewModel : BaseModel
return true;
}
+ internal string SelectFile()
+ {
+ var dlg = new Microsoft.Win32.OpenFileDialog();
+ var result = dlg.ShowDialog();
+ if (result == true)
+ return dlg.FileName;
+
+ return string.Empty;
+ }
+
[RelayCommand]
private void Add()
{
diff --git a/Flow.Launcher/ViewModel/SelectFileManagerViewModel.cs b/Flow.Launcher/ViewModel/SelectFileManagerViewModel.cs
index a72eff280..77f004980 100644
--- a/Flow.Launcher/ViewModel/SelectFileManagerViewModel.cs
+++ b/Flow.Launcher/ViewModel/SelectFileManagerViewModel.cs
@@ -108,9 +108,7 @@ public partial class SelectFileManagerViewModel : BaseModel
var dlg = new Microsoft.Win32.OpenFileDialog();
var result = dlg.ShowDialog();
if (result == true)
- {
return dlg.FileName;
- }
return string.Empty;
}
From edae4328527e68dbca8d71fd343f154bb453b3ea Mon Sep 17 00:00:00 2001
From: DB p
Date: Thu, 22 May 2025 04:14:30 +0900
Subject: [PATCH 1297/1697] Add FocusQueryTextBox method to set focus on the
query text box in MainWindow
---
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 5 +++++
Flow.Launcher/PublicAPIInstance.cs | 13 +++++++++++++
Plugins/Flow.Launcher.Plugin.Shell/Main.cs | 7 +++++--
3 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index d4eb02a90..cb60251ed 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -88,6 +88,11 @@ namespace Flow.Launcher.Plugin
/// Show the MainWindow when hiding
///
void ShowMainWindow();
+
+ ///
+ /// Focus the query text box in the main window
+ ///
+ void FocusQueryTextBox();
///
/// Hide MainWindow
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index a0614d90f..7b80ec480 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -33,6 +33,7 @@ using JetBrains.Annotations;
using Squirrel;
using Stopwatch = Flow.Launcher.Infrastructure.Stopwatch;
using System.ComponentModel;
+using System.Windows.Input;
namespace Flow.Launcher
{
@@ -92,6 +93,18 @@ namespace Flow.Launcher
}
public void ShowMainWindow() => _mainVM.Show();
+
+ public void FocusQueryTextBox()
+ {
+ Application.Current.Dispatcher.Invoke(new Action(() =>
+ {
+ if (Application.Current.MainWindow is MainWindow mw)
+ {
+ mw.QueryTextBox.Focus();
+ Keyboard.Focus(mw.QueryTextBox);
+ }
+ }));
+ }
public void HideMainWindow() => _mainVM.Hide();
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
index 0d395c053..758ad09d5 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
@@ -378,10 +378,13 @@ namespace Flow.Launcher.Plugin.Shell
private void OnWinRPressed()
{
+ Context.API.ShowMainWindow();
// show the main window and set focus to the query box
- _ = Task.Run(() =>
+ _ = Task.Run(async () =>
{
- Context.API.ShowMainWindow();
+ await Task.Delay(50); // 💡 키보드 이벤트 처리가 끝난 뒤
+ Context.API.FocusQueryTextBox();
+
Context.API.ChangeQuery($"{Context.CurrentPluginMetadata.ActionKeywords[0]}{Plugin.Query.TermSeparator}");
});
}
From 3718ae5640bbe5e9af2a389964386d9d81444114 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 22 May 2025 10:39:09 +0800
Subject: [PATCH 1298/1697] Improve code quality & Improve code comments
---
Flow.Launcher/PublicAPIInstance.cs | 18 ++++--------------
Flow.Launcher/ViewModel/MainViewModel.cs | 15 +++++++++++++++
Plugins/Flow.Launcher.Plugin.Shell/Main.cs | 9 ++++++---
3 files changed, 25 insertions(+), 17 deletions(-)
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 7b80ec480..66e11f881 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -2,6 +2,7 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Specialized;
+using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
@@ -10,6 +11,7 @@ using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
+using System.Windows.Input;
using System.Windows.Media;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Core;
@@ -32,8 +34,6 @@ using Flow.Launcher.ViewModel;
using JetBrains.Annotations;
using Squirrel;
using Stopwatch = Flow.Launcher.Infrastructure.Stopwatch;
-using System.ComponentModel;
-using System.Windows.Input;
namespace Flow.Launcher
{
@@ -93,18 +93,8 @@ namespace Flow.Launcher
}
public void ShowMainWindow() => _mainVM.Show();
-
- public void FocusQueryTextBox()
- {
- Application.Current.Dispatcher.Invoke(new Action(() =>
- {
- if (Application.Current.MainWindow is MainWindow mw)
- {
- mw.QueryTextBox.Focus();
- Keyboard.Focus(mw.QueryTextBox);
- }
- }));
- }
+
+ public void FocusQueryTextBox() => _mainVM.FocusQueryTextBox();
public void HideMainWindow() => _mainVM.Hide();
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 807275fcb..6e1b0dd93 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1926,6 +1926,21 @@ namespace Flow.Launcher.ViewModel
Results.AddResults(resultsForUpdates, token, reSelect);
}
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "")]
+ public void FocusQueryTextBox()
+ {
+ // When application is exiting, the Application.Current will be null
+ Application.Current?.Dispatcher.Invoke(() =>
+ {
+ // When application is exiting, the Application.Current will be null
+ if (Application.Current?.MainWindow is MainWindow window)
+ {
+ window.QueryTextBox.Focus();
+ Keyboard.Focus(window.QueryTextBox);
+ }
+ });
+ }
+
#endregion
#region IDisposable
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
index 758ad09d5..2613c770b 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
@@ -382,10 +382,13 @@ namespace Flow.Launcher.Plugin.Shell
// show the main window and set focus to the query box
_ = Task.Run(async () =>
{
- await Task.Delay(50); // 💡 키보드 이벤트 처리가 끝난 뒤
- Context.API.FocusQueryTextBox();
-
Context.API.ChangeQuery($"{Context.CurrentPluginMetadata.ActionKeywords[0]}{Plugin.Query.TermSeparator}");
+
+ // Win+R is a system-reserved shortcut, and though the plugin intercepts the keyboard event and
+ // shows the main window, Windows continues to process the Win key and briefly reclaims focus.
+ // So we need to wait until the keyboard event processing is completed and then set focus
+ await Task.Delay(50);
+ Context.API.FocusQueryTextBox();
});
}
From 8aae92e61da289815da6d8f5291b5718c6741340 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 22 May 2025 10:47:07 +0800
Subject: [PATCH 1299/1697] Fix main window null when checking exitting
---
Flow.Launcher/App.xaml.cs | 2 +-
Flow.Launcher/SettingWindow.xaml.cs | 2 +-
Flow.Launcher/ViewModel/MainViewModel.cs | 2 +-
Flow.Launcher/WelcomeWindow.xaml.cs | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 969bb75bb..cedced181 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -32,7 +32,7 @@ namespace Flow.Launcher
#region Public Properties
public static IPublicAPI API { get; private set; }
- public static bool Exiting => _mainWindow.CanClose;
+ public static bool LoadingOrExiting => _mainWindow == null || _mainWindow.CanClose;
#endregion
diff --git a/Flow.Launcher/SettingWindow.xaml.cs b/Flow.Launcher/SettingWindow.xaml.cs
index c53a4ea80..c1c0f96a7 100644
--- a/Flow.Launcher/SettingWindow.xaml.cs
+++ b/Flow.Launcher/SettingWindow.xaml.cs
@@ -82,7 +82,7 @@ public partial class SettingWindow
_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;
+ if (App.LoadingOrExiting) return;
// Save settings when window is closed
_settings.Save();
App.API.SavePluginSettings();
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 807275fcb..c4da384f8 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1729,7 +1729,7 @@ namespace Flow.Launcher.ViewModel
public void Show()
{
// When application is exiting, we should not show the main window
- if (App.Exiting) return;
+ if (App.LoadingOrExiting) return;
// When application is exiting, the Application.Current will be null
Application.Current?.Dispatcher.Invoke(() =>
diff --git a/Flow.Launcher/WelcomeWindow.xaml.cs b/Flow.Launcher/WelcomeWindow.xaml.cs
index ef0706765..fe8a63e52 100644
--- a/Flow.Launcher/WelcomeWindow.xaml.cs
+++ b/Flow.Launcher/WelcomeWindow.xaml.cs
@@ -96,7 +96,7 @@ namespace Flow.Launcher
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;
+ if (App.LoadingOrExiting) return;
// Save settings when window is closed
_settings.Save();
}
From 949344a51e9062828e800149adb91165cc8882c3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 22 May 2025 17:32:33 +0800
Subject: [PATCH 1300/1697] Add internal model for plugin management
---
.../UserSettings/Settings.cs | 2 +
Flow.Launcher/Languages/en.xaml | 18 ++
.../Views/SettingsPaneGeneral.xaml | 11 +
.../ViewModel/PluginStoreItemViewModel.cs | 270 ++++++++++++++++--
Flow.Launcher/ViewModel/PluginViewModel.cs | 23 +-
5 files changed, 280 insertions(+), 44 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index ce1269a29..024e727ce 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -176,6 +176,8 @@ namespace Flow.Launcher.Infrastructure.UserSettings
public bool ShowHistoryResultsForHomePage { get; set; } = false;
public int MaxHistoryResultsToShowForHomePage { get; set; } = 5;
+ public bool AutoRestartAfterChanging { get; set; } = false;
+
public int CustomExplorerIndex { get; set; } = 0;
[JsonIgnore]
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 22ab2016c..24f74e15d 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -131,6 +131,8 @@
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.
+ Automatically restart after changing plugins
+ Automatically restart Flow Launcher after installing/uninstalling/updating plugins
Search Plugin
@@ -184,6 +186,22 @@
New Version
This plugin has been updated within the last 7 days
New Update is Available
+ Error installing plugin
+ Error uninstalling plugin
+ Error updating plugin
+ Keep plugin settings
+ Do you want to keep the settings of the plugin for the next usage?
+ Plugin {0} successfully installed. Please restart Flow.
+ Plugin {0} successfully uninstalled. Please restart Flow.
+ Plugin {0} successfully updated. Please restart Flow.
+ Plugin install
+ {0} by {1} {2}{2}Would you like to install this plugin?
+ Plugin uninstall
+ {0} by {1} {2}{2}Would you like to uninstall this plugin?
+ Plugin udpate
+ {0} by {1} {2}{2}Would you like to update this plugin?
+ Downloading plugin
+ Automatically restart after installing/uninstalling/updating plugins in plugin store
Theme
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
index c0c5613de..452e026d7 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
@@ -202,6 +202,17 @@
+
+
+
+
PluginManager.GetPluginForId("9f8f9b14-2518-4907-b211-35ab6290dee7");
+ private static readonly string ClassName = nameof(PluginStoreItemViewModel);
+
+ private static readonly Settings Settings = Ioc.Default.GetRequiredService();
+
+ private readonly UserPlugin _newPlugin;
+ private readonly PluginPair _oldPluginPair;
+
public PluginStoreItemViewModel(UserPlugin plugin)
{
- _plugin = plugin;
+ _newPlugin = plugin;
+ _oldPluginPair = PluginManager.GetPluginForId(plugin.ID);
}
- private UserPlugin _plugin;
+ public string ID => _newPlugin.ID;
+ public string Name => _newPlugin.Name;
+ public string Description => _newPlugin.Description;
+ public string Author => _newPlugin.Author;
+ public string Version => _newPlugin.Version;
+ public string Language => _newPlugin.Language;
+ public string Website => _newPlugin.Website;
+ public string UrlDownload => _newPlugin.UrlDownload;
+ public string UrlSourceCode => _newPlugin.UrlSourceCode;
+ public string IcoPath => _newPlugin.IcoPath;
- public string ID => _plugin.ID;
- public string Name => _plugin.Name;
- public string Description => _plugin.Description;
- public string Author => _plugin.Author;
- public string Version => _plugin.Version;
- public string Language => _plugin.Language;
- public string Website => _plugin.Website;
- public string UrlDownload => _plugin.UrlDownload;
- public string UrlSourceCode => _plugin.UrlSourceCode;
- public string IcoPath => _plugin.IcoPath;
-
- public bool LabelInstalled => PluginManager.GetPluginForId(_plugin.ID) != null;
- public bool LabelUpdate => LabelInstalled && new Version(_plugin.Version) > new Version(PluginManager.GetPluginForId(_plugin.ID).Metadata.Version);
+ public bool LabelInstalled => _oldPluginPair != null;
+ public bool LabelUpdate => LabelInstalled && new Version(_newPlugin.Version) > new Version(_oldPluginPair.Metadata.Version);
internal const string None = "None";
internal const string RecentlyUpdated = "RecentlyUpdated";
@@ -41,15 +51,15 @@ namespace Flow.Launcher.ViewModel
get
{
string category = None;
- if (DateTime.Now - _plugin.LatestReleaseDate < TimeSpan.FromDays(7))
+ if (DateTime.Now - _newPlugin.LatestReleaseDate < TimeSpan.FromDays(7))
{
category = RecentlyUpdated;
}
- if (DateTime.Now - _plugin.DateAdded < TimeSpan.FromDays(7))
+ if (DateTime.Now - _newPlugin.DateAdded < TimeSpan.FromDays(7))
{
category = NewRelease;
}
- if (PluginManager.GetPluginForId(_plugin.ID) != null)
+ if (_oldPluginPair != null)
{
category = Installed;
}
@@ -59,11 +69,223 @@ namespace Flow.Launcher.ViewModel
}
[RelayCommand]
- private void ShowCommandQuery(string action)
+ private async Task ShowCommandQueryAsync(string action)
{
- var actionKeyword = PluginManagerData.Metadata.ActionKeywords.Any() ? PluginManagerData.Metadata.ActionKeywords[0] + " " : String.Empty;
- App.API.ChangeQuery($"{actionKeyword}{action} {_plugin.Name}");
- App.API.ShowMainWindow();
+ switch (action)
+ {
+ case "install":
+ await InstallPluginAsync(_newPlugin);
+ break;
+ case "uninstall":
+ await UninstallPluginAsync(_oldPluginPair.Metadata);
+ break;
+ case "update":
+ await UpdatePluginAsync(_newPlugin, _oldPluginPair.Metadata);
+ break;
+ }
+ }
+
+ internal static async Task InstallPluginAsync(UserPlugin newPlugin)
+ {
+ if (App.API.ShowMsgBox(
+ string.Format(
+ App.API.GetTranslation("InstallPromptSubtitle"),
+ newPlugin.Name, newPlugin.Author, Environment.NewLine),
+ App.API.GetTranslation("InstallPromptTitle"),
+ button: MessageBoxButton.YesNo) != MessageBoxResult.Yes) return;
+
+ try
+ {
+ // at minimum should provide a name, but handle plugin that is not downloaded from plugins manifest and is a url download
+ var downloadFilename = string.IsNullOrEmpty(newPlugin.Version)
+ ? $"{newPlugin.Name}-{Guid.NewGuid()}.zip"
+ : $"{newPlugin.Name}-{newPlugin.Version}.zip";
+
+ var filePath = Path.Combine(Path.GetTempPath(), downloadFilename);
+
+ using var cts = new CancellationTokenSource();
+
+ if (!newPlugin.IsFromLocalInstallPath)
+ {
+ await DownloadFileAsync(
+ $"{App.API.GetTranslation("DownloadingPlugin")} {newPlugin.Name}",
+ newPlugin.UrlDownload, filePath, cts);
+ }
+ else
+ {
+ filePath = newPlugin.LocalInstallPath;
+ }
+
+ // check if user cancelled download before installing plugin
+ if (cts.IsCancellationRequested)
+ {
+ return;
+ }
+ else
+ {
+ if (!File.Exists(filePath))
+ {
+ throw new FileNotFoundException($"Plugin {newPlugin.ID} zip file not found at {filePath}", filePath);
+ }
+
+ App.API.InstallPlugin(newPlugin, filePath);
+
+ if (!newPlugin.IsFromLocalInstallPath)
+ {
+ File.Delete(filePath);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ App.API.LogException(ClassName, "Failed to install plugin", e);
+ App.API.ShowMsgError(App.API.GetTranslation("ErrorInstallingPlugin"));
+ }
+
+ if (Settings.AutoRestartAfterChanging)
+ {
+ App.API.RestartApp();
+ }
+ else
+ {
+ App.API.ShowMsg(
+ App.API.GetTranslation("installbtn"),
+ string.Format(
+ App.API.GetTranslation(
+ "InstallSuccessNoRestart"),
+ newPlugin.Name));
+ }
+ }
+
+ internal static async Task UninstallPluginAsync(PluginMetadata oldPlugin)
+ {
+ if (App.API.ShowMsgBox(
+ string.Format(
+ App.API.GetTranslation("UninstallPromptSubtitle"),
+ oldPlugin.Name, oldPlugin.Author, Environment.NewLine),
+ App.API.GetTranslation("UninstallPromptTitle"),
+ button: MessageBoxButton.YesNo) != MessageBoxResult.Yes) return;
+
+ var removePluginSettings = App.API.ShowMsgBox(
+ App.API.GetTranslation("KeepPluginSettingsSubtitle"),
+ App.API.GetTranslation("KeepPluginSettingsTitle"),
+ button: MessageBoxButton.YesNo) == MessageBoxResult.No;
+
+ try
+ {
+ await App.API.UninstallPluginAsync(oldPlugin, removePluginSettings);
+ }
+ catch (Exception e)
+ {
+ App.API.LogException(ClassName, "Failed to uninstall plugin", e);
+ App.API.ShowMsgError(App.API.GetTranslation("ErrorUninstallingPlugin"));
+ }
+
+ if (Settings.AutoRestartAfterChanging)
+ {
+ App.API.RestartApp();
+ }
+ else
+ {
+ App.API.ShowMsg(
+ App.API.GetTranslation("uninstallbtn"),
+ string.Format(
+ App.API.GetTranslation(
+ "UninstallSuccessNoRestart"),
+ oldPlugin.Name));
+ }
+ }
+
+ internal static async Task UpdatePluginAsync(UserPlugin newPlugin, PluginMetadata oldPlugin)
+ {
+ if (App.API.ShowMsgBox(
+ string.Format(
+ App.API.GetTranslation("UpdatePromptSubtitle"),
+ oldPlugin.Name, oldPlugin.Author, Environment.NewLine),
+ App.API.GetTranslation("UpdatePromptTitle"),
+ button: MessageBoxButton.YesNo) != MessageBoxResult.Yes) return;
+
+ try
+ {
+ var filePath = Path.Combine(Path.GetTempPath(), $"{newPlugin.Name}-{newPlugin.Version}.zip");
+
+ using var cts = new CancellationTokenSource();
+
+ if (!newPlugin.IsFromLocalInstallPath)
+ {
+ await DownloadFileAsync(
+ $"{App.API.GetTranslation("DownloadingPlugin")} {newPlugin.Name}",
+ newPlugin.UrlDownload, filePath, cts);
+ }
+ else
+ {
+ filePath = newPlugin.LocalInstallPath;
+ }
+
+ // check if user cancelled download before installing plugin
+ if (cts.IsCancellationRequested)
+ {
+ return;
+ }
+ else
+ {
+ await App.API.UpdatePluginAsync(oldPlugin, newPlugin, filePath);
+ }
+ }
+ catch (Exception e)
+ {
+ App.API.LogException(ClassName, "Failed to update plugin", e);
+ App.API.ShowMsgError(App.API.GetTranslation("ErrorUpdatingPlugin"));
+ }
+
+ if (Settings.AutoRestartAfterChanging)
+ {
+ App.API.RestartApp();
+ }
+ else
+ {
+ App.API.ShowMsg(
+ App.API.GetTranslation("updatebtn"),
+ string.Format(
+ App.API.GetTranslation(
+ "UpdateSuccessNoRestart"),
+ newPlugin.Name));
+ }
+ }
+
+ private static async Task DownloadFileAsync(string prgBoxTitle, string downloadUrl, string filePath, CancellationTokenSource cts, bool deleteFile = true, bool showProgress = true)
+ {
+ if (deleteFile && File.Exists(filePath))
+ File.Delete(filePath);
+
+ if (showProgress)
+ {
+ var exceptionHappened = false;
+ await App.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 App.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 App.API.HttpDownloadAsync(downloadUrl, filePath, token: cts.Token).ConfigureAwait(false);
+ }
+ else
+ {
+ await App.API.HttpDownloadAsync(downloadUrl, filePath, token: cts.Token).ConfigureAwait(false);
+ }
}
}
}
diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs
index 01fa3d203..bda05a02d 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -1,5 +1,4 @@
-using System.Linq;
-using System.Threading.Tasks;
+using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
@@ -32,21 +31,6 @@ namespace Flow.Launcher.ViewModel
}
}
- private static string PluginManagerActionKeyword
- {
- get
- {
- var keyword = PluginManager
- .GetPluginForId("9f8f9b14-2518-4907-b211-35ab6290dee7")
- .Metadata.ActionKeywords.FirstOrDefault();
- return keyword switch
- {
- null or "*" => string.Empty,
- _ => keyword
- };
- }
- }
-
private async Task LoadIconAsync()
{
Image = await App.API.LoadImageAsync(PluginPair.Metadata.IcoPath);
@@ -186,10 +170,9 @@ namespace Flow.Launcher.ViewModel
}
[RelayCommand]
- private void OpenDeletePluginWindow()
+ private async Task OpenDeletePluginWindowAsync()
{
- App.API.ChangeQuery($"{PluginManagerActionKeyword} uninstall {PluginPair.Metadata.Name}".Trim(), true);
- App.API.ShowMainWindow();
+ await PluginStoreItemViewModel.UninstallPluginAsync(PluginPair.Metadata);
}
[RelayCommand]
From 76736b785091873534770d4806572f2641f20adf Mon Sep 17 00:00:00 2001
From: Jack Ye <1160210343@qq.com>
Date: Thu, 22 May 2025 17:37:27 +0800
Subject: [PATCH 1301/1697] Fix typo
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
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 24f74e15d..2166bdd8c 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -198,7 +198,7 @@
{0} by {1} {2}{2}Would you like to install this plugin?
Plugin uninstall
{0} by {1} {2}{2}Would you like to uninstall this plugin?
- Plugin udpate
+ Plugin update
{0} by {1} {2}{2}Would you like to update this plugin?
Downloading plugin
Automatically restart after installing/uninstalling/updating plugins in plugin store
From c6c7ff882e6745216c828559191966753553e839 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 22 May 2025 17:40:26 +0800
Subject: [PATCH 1302/1697] Handle default
---
Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs b/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs
index 3e823d635..a69c0dbd7 100644
--- a/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs
@@ -82,6 +82,8 @@ namespace Flow.Launcher.ViewModel
case "update":
await UpdatePluginAsync(_newPlugin, _oldPluginPair.Metadata);
break;
+ default:
+ break;
}
}
From 6044f87e806c97cd96f9d62beb6fb3a868ba1efe Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 22 May 2025 17:41:13 +0800
Subject: [PATCH 1303/1697] Do not restart on failure
---
Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs b/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs
index a69c0dbd7..6b2cf6eed 100644
--- a/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs
@@ -142,6 +142,7 @@ namespace Flow.Launcher.ViewModel
{
App.API.LogException(ClassName, "Failed to install plugin", e);
App.API.ShowMsgError(App.API.GetTranslation("ErrorInstallingPlugin"));
+ return; // don’t restart on failure
}
if (Settings.AutoRestartAfterChanging)
@@ -181,6 +182,7 @@ namespace Flow.Launcher.ViewModel
{
App.API.LogException(ClassName, "Failed to uninstall plugin", e);
App.API.ShowMsgError(App.API.GetTranslation("ErrorUninstallingPlugin"));
+ return; // don’t restart on failure
}
if (Settings.AutoRestartAfterChanging)
@@ -238,6 +240,7 @@ namespace Flow.Launcher.ViewModel
{
App.API.LogException(ClassName, "Failed to update plugin", e);
App.API.ShowMsgError(App.API.GetTranslation("ErrorUpdatingPlugin"));
+ return; // don’t restart on failure
}
if (Settings.AutoRestartAfterChanging)
From 087a45c66458c700b5f9f0e28278fe2abd34938a Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Thu, 22 May 2025 20:41:04 +1000
Subject: [PATCH 1304/1697] New Crowdin updates (#3559)
---
Flow.Launcher/Languages/ar.xaml | 11 +++++++++++
Flow.Launcher/Languages/cs.xaml | 11 +++++++++++
Flow.Launcher/Languages/da.xaml | 11 +++++++++++
Flow.Launcher/Languages/de.xaml | 11 +++++++++++
Flow.Launcher/Languages/es-419.xaml | 11 +++++++++++
Flow.Launcher/Languages/es.xaml | 11 +++++++++++
Flow.Launcher/Languages/fr.xaml | 11 +++++++++++
Flow.Launcher/Languages/he.xaml | 11 +++++++++++
Flow.Launcher/Languages/it.xaml | 11 +++++++++++
Flow.Launcher/Languages/ja.xaml | 11 +++++++++++
Flow.Launcher/Languages/ko.xaml | 11 +++++++++++
Flow.Launcher/Languages/nb.xaml | 11 +++++++++++
Flow.Launcher/Languages/nl.xaml | 11 +++++++++++
Flow.Launcher/Languages/pl.xaml | 11 +++++++++++
Flow.Launcher/Languages/pt-br.xaml | 11 +++++++++++
Flow.Launcher/Languages/pt-pt.xaml | 11 +++++++++++
Flow.Launcher/Languages/ru.xaml | 11 +++++++++++
Flow.Launcher/Languages/sk.xaml | 13 ++++++++++++-
Flow.Launcher/Languages/sr.xaml | 11 +++++++++++
Flow.Launcher/Languages/tr.xaml | 11 +++++++++++
Flow.Launcher/Languages/uk-UA.xaml | 11 +++++++++++
Flow.Launcher/Languages/vi.xaml | 11 +++++++++++
Flow.Launcher/Languages/zh-cn.xaml | 11 +++++++++++
Flow.Launcher/Languages/zh-tw.xaml | 11 +++++++++++
.../Properties/Resources.ja-JP.resx | 6 +++---
25 files changed, 268 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher/Languages/ar.xaml b/Flow.Launcher/Languages/ar.xaml
index b81c5c9b5..42cfdf3eb 100644
--- a/Flow.Launcher/Languages/ar.xaml
+++ b/Flow.Launcher/Languages/ar.xaml
@@ -371,6 +371,7 @@
اختر مدير الملفات
+ Learn more
يرجى تحديد موقع ملف مدير الملفات الذي تستخدمه وإضافة الحجج حسب الحاجة. يمثل "%d" مسار الدليل المفتوح، ويستخدمه الحقل "الحجة للمجلد" للأوامر التي تفتح أدلة محددة. يمثل "%f" مسار الملف المفتوح، ويستخدمه الحقل "الحجة للملف" للأوامر التي تفتح ملفات محددة.
على سبيل المثال، إذا كان مدير الملفات يستخدم أمرًا مثل "totalcmd.exe /A c:\windows" لفتح دليل c:\windows، فإن مسار مدير الملفات سيكون totalcmd.exe، وحجة المجلد ستكون /A "%d". قد تحتاج بعض مديري الملفات مثل QTTabBar فقط إلى توفير مسار، في هذه الحالة استخدم "%d" كمسار مدير الملفات واترك باقي الحقول فارغة.
مدير الملفات
@@ -378,6 +379,8 @@
مسار مدير الملفات
حجة للمجلد
حجة للملف
+ The file manager '{0}' could not be located at '{1}'. Would you like to continue?
+ File Manager Path Error
متصفح الويب الافتراضي
@@ -469,6 +472,14 @@
1. Upload log file: {0}
2. Copy below exception message
+
+ File Manager Error
+
+ The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General.
+
+ خطأ
+ An error occurred while opening the folder. {0}
+
يرجى الانتظار...
diff --git a/Flow.Launcher/Languages/cs.xaml b/Flow.Launcher/Languages/cs.xaml
index 71c9c8c6b..bfcd92360 100644
--- a/Flow.Launcher/Languages/cs.xaml
+++ b/Flow.Launcher/Languages/cs.xaml
@@ -371,6 +371,7 @@
Vybrat správce souborů
+ Learn more
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.
Správce souborů
@@ -378,6 +379,8 @@
Cesta k správci souborů
Argumenty pro složku
Argumenty pro Soubor
+ The file manager '{0}' could not be located at '{1}'. Would you like to continue?
+ File Manager Path Error
Výchozí prohlížeč
@@ -469,6 +472,14 @@ Pokud před zkratku při zadávání přidáte znak "@", bude odpovíd
1. Upload log file: {0}
2. Copy below exception message
+
+ File Manager Error
+
+ The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General.
+
+ Chyba
+ An error occurred while opening the folder. {0}
+
Počkejte prosím...
diff --git a/Flow.Launcher/Languages/da.xaml b/Flow.Launcher/Languages/da.xaml
index 37723dc9b..9a4cbc003 100644
--- a/Flow.Launcher/Languages/da.xaml
+++ b/Flow.Launcher/Languages/da.xaml
@@ -371,6 +371,7 @@
Select File Manager
+ Learn more
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.
Filhåndtering
@@ -378,6 +379,8 @@
Sti til filhåndtering
Arg for mappe
Arg for fil
+ The file manager '{0}' could not be located at '{1}'. Would you like to continue?
+ File Manager Path Error
Default Web Browser
@@ -469,6 +472,14 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
1. Upload log file: {0}
2. Copy below exception message
+
+ File Manager Error
+
+ The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General.
+
+ Error
+ An error occurred while opening the folder. {0}
+
Please wait...
diff --git a/Flow.Launcher/Languages/de.xaml b/Flow.Launcher/Languages/de.xaml
index 895a2dab6..88c5b84d4 100644
--- a/Flow.Launcher/Languages/de.xaml
+++ b/Flow.Launcher/Languages/de.xaml
@@ -371,6 +371,7 @@
Dateimanager auswählen
+ Learn more
Bitte geben Sie den Dateiort des von Ihnen verwendeten Dateimanagers an und fügen Sie bei Bedarf Argumente hinzu. Das „%d“ repräsentiert den dafür zu öffnenden Verzeichnispfad, der vom Feld Arg for Folder und für Befehle zum Öffnen bestimmter Verzeichnisse verwendet wird. Das „%f“ repräsentiert den dafür zu öffnenden Dateipfad, der vom Feld Arg for File und für Befehle zum Öffnen bestimmter Dateien verwendet wird.
Zum Beispiel, wenn der Dateimanager einen Befehl wie „totalcmd.exe /A c:\windows“ verwendet, um das Verzeichnis c:\windows zu öffnen, lautet der Dateimanager-Pfad „totalcmd.exe“ und der Arg for Folder „/A %d“. Bestimmte Dateimanager wie QTTabBar kann nur die Angabe eines Pfades erfordern, in diesem Fall verwenden Sie „%d“ als den Dateimanager-Pfad und lassen den Rest der Felder blank.
Dateimanager
@@ -378,6 +379,8 @@
Dateimanager-Pfad
Arg For Folder
Arg For File
+ The file manager '{0}' could not be located at '{1}'. Would you like to continue?
+ File Manager Path Error
Webbrowser per Default
@@ -469,6 +472,14 @@ Wenn Sie bei der Eingabe eines Shortcuts ein '@'-Präfix hinzufügen, stimmt die
1. Logdatei hochladen: {0}
2. Kopieren Sie die Ausnahmemeldung unterhalb
+
+ File Manager Error
+
+ The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General.
+
+ Fehler
+ An error occurred while opening the folder. {0}
+
Bitte warten Sie ...
diff --git a/Flow.Launcher/Languages/es-419.xaml b/Flow.Launcher/Languages/es-419.xaml
index 902811a56..b73a1ef12 100644
--- a/Flow.Launcher/Languages/es-419.xaml
+++ b/Flow.Launcher/Languages/es-419.xaml
@@ -371,6 +371,7 @@
Seleccionar Gestor de Archivos
+ Learn more
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.
Gestor de Archivos
@@ -378,6 +379,8 @@
Ruta del Gestor de Archivos
Arg para Carpeta
Arg para Archivo
+ The file manager '{0}' could not be located at '{1}'. Would you like to continue?
+ File Manager Path Error
Navegador Web Predeterminado
@@ -469,6 +472,14 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
1. Upload log file: {0}
2. Copy below exception message
+
+ File Manager Error
+
+ The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General.
+
+ Error
+ An error occurred while opening the folder. {0}
+
Por favor espere...
diff --git a/Flow.Launcher/Languages/es.xaml b/Flow.Launcher/Languages/es.xaml
index 0dc6833af..2b6074f06 100644
--- a/Flow.Launcher/Languages/es.xaml
+++ b/Flow.Launcher/Languages/es.xaml
@@ -371,6 +371,7 @@
Seleccionar administrador de archivos
+ Learn more
Especifique la ubicación del archivo del administrador de archivos que está utilizando y añada los argumentos necesarios. El argumento "%d" representa la ruta del directorio a abrir, utilizada por el campo Argumentos de la carpeta y por comandos que abren directorios específicos. El "%f" representa la ruta del archivo a abrir, utilizada por el campo Argumentos del archivo y por comandos que abren archivos específicos.
Por ejemplo, si el administrador de archivos utiliza un comando como "totalcmd.exe /A c:\windows" para abrir el directorio c:\windows, la ruta del administrador de archivos será totalcmd.exe, y los Argumentos de la carpeta serán /A "%d". Ciertos administradores de archivos como QTTabBar pueden requerir solo la ruta, en este caso utilice "%d" como la ruta del administrador de archivos y deje el resto de los campos en blanco.
Administrador de archivos
@@ -378,6 +379,8 @@
Ruta del administrador de archivos
Argumentos de la carpeta
Argumentos del archivo
+ The file manager '{0}' could not be located at '{1}'. Would you like to continue?
+ File Manager Path Error
Navegador web predeterminado
@@ -469,6 +472,14 @@ Si añade un prefijo "@" al introducir un acceso directo, éste coinci
1. Subir archivo de registro: {0}
2. Copiar el siguiente mensaje de excepción
+
+ File Manager Error
+
+ The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General.
+
+ Error
+ An error occurred while opening the folder. {0}
+
Por favor espere...
diff --git a/Flow.Launcher/Languages/fr.xaml b/Flow.Launcher/Languages/fr.xaml
index 41fdbaa51..cd6d8c01f 100644
--- a/Flow.Launcher/Languages/fr.xaml
+++ b/Flow.Launcher/Languages/fr.xaml
@@ -370,6 +370,7 @@
Sélectionner le gestionnaire de fichiers
+ Learn more
Veuillez spécifier l'emplacement du fichier de l'explorateur de fichiers que vous utilisez et ajouter des arguments si nécessaire. Le "%d" représente le chemin du répertoire à ouvrir, utilisé par le champ Arg for Folder et pour les commandes ouvrant des répertoires spécifiques. Le "%f" représente le chemin du fichier à ouvrir, utilisé par le champ Arg for File et pour les commandes ouvrant des fichiers spécifiques.
Par exemple, si l'explorateur de fichiers utilise une commande telle que "totalcmd.exe /A c:\windows" pour ouvrir le répertoire c:\windows, le chemin de l'explorateur de fichiers sera totalcmd.exe et l'argument Arg For Folder sera /A "%d"". Certains explorateurs de fichiers comme QTTabBar peuvent simplement nécessiter qu'un chemin soit fourni, dans ce cas, utilisez "%d" comme chemin de l'explorateur de fichiers et laissez le reste des fichiers vides.
Gestionnaire de fichiers
@@ -377,6 +378,8 @@
Chemin du gestionnaire de fichiers
Arguments pour le répertoire
Arguments pour le fichier
+ The file manager '{0}' could not be located at '{1}'. Would you like to continue?
+ File Manager Path Error
Navigateur web par défaut
@@ -468,6 +471,14 @@ Si vous ajoutez un préfixe "@" lors de la saisie d'un raccourci, celu
1. Télécharger le fichier journal : {0}
2. Copiez le message d’exception ci-dessous
+
+ File Manager Error
+
+ The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General.
+
+ Erreur
+ An error occurred while opening the folder. {0}
+
Veuillez patienter...
diff --git a/Flow.Launcher/Languages/he.xaml b/Flow.Launcher/Languages/he.xaml
index 52eaf5e9f..b98c2ec73 100644
--- a/Flow.Launcher/Languages/he.xaml
+++ b/Flow.Launcher/Languages/he.xaml
@@ -370,6 +370,7 @@
בחר מנהל קבצים
+ Learn more
אנא ציין את מיקום הקובץ של מנהל הקבצים שבו אתה משתמש והוסף ארגומנטים כנדרש. "%d" מייצג את נתיב התיקייה שיש לפתוח, ומשמש בשדה ארגומנט לתיקייה ובפקודות לפתיחת תיקיות מסוימות. "%f" מייצג את נתיב הקובץ שיש לפתוח, ומשמש בשדה ארגומנט לקובץ ובפקודות לפתיחת קבצים מסוימים.
לדוגמה, אם מנהל הקבצים משתמש בפקודה כגון "totalcmd.exe /A c:\windows" כדי לפתוח את התיקייה c:\windows, נתיב מנהל הקבצים יהיה totalcmd.exe, והארגומנט לתיקייה יהיה /A "%d". מנהלי קבצים מסוימים, כגון QTTabBar, עשויים לדרוש רק ציון נתיב, במקרה כזה השתמש ב-"%d" כנתיב מנהל הקבצים והשאר את שאר השדות ריקים.
מנהל קבצים
@@ -377,6 +378,8 @@
נתיב מנהל קבצים
ארגומנט לתיקייה
ארגומנט לקובץ
+ The file manager '{0}' could not be located at '{1}'. Would you like to continue?
+ File Manager Path Error
דפדפן ברירת מחדל
@@ -468,6 +471,14 @@
1. העלה קובץ יומן: {0}
2. העתק את הודעת החריגה למטה
+
+ File Manager Error
+
+ The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General.
+
+ שגיאה
+ An error occurred while opening the folder. {0}
+
אנא המתן...
diff --git a/Flow.Launcher/Languages/it.xaml b/Flow.Launcher/Languages/it.xaml
index 1a356ad65..7ea797fa9 100644
--- a/Flow.Launcher/Languages/it.xaml
+++ b/Flow.Launcher/Languages/it.xaml
@@ -371,6 +371,7 @@
Seleziona Gestore File
+ Learn more
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.
Gestore File
@@ -378,6 +379,8 @@
Percorso Gestore File
Arg Per Cartella
Arg Per Cartella
+ The file manager '{0}' could not be located at '{1}'. Would you like to continue?
+ File Manager Path Error
Browser predefinito
@@ -469,6 +472,14 @@ Se si aggiunge un prefisso '@' mentre si inserisce una scorciatoia, corrisponde
1. Upload log file: {0}
2. Copy below exception message
+
+ File Manager Error
+
+ The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General.
+
+ Error
+ An error occurred while opening the folder. {0}
+
Attendere prego...
diff --git a/Flow.Launcher/Languages/ja.xaml b/Flow.Launcher/Languages/ja.xaml
index 949fe5c99..33673d60f 100644
--- a/Flow.Launcher/Languages/ja.xaml
+++ b/Flow.Launcher/Languages/ja.xaml
@@ -371,6 +371,7 @@
デフォルトのファイルマネージャー
+ Learn more
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
@@ -378,6 +379,8 @@
File Manager Path
Arg For Folder
Arg For File
+ The file manager '{0}' could not be located at '{1}'. Would you like to continue?
+ File Manager Path Error
デフォルトのウェブブラウザー
@@ -469,6 +472,14 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
1. Upload log file: {0}
2. Copy below exception message
+
+ File Manager Error
+
+ The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General.
+
+ Error
+ An error occurred while opening the folder. {0}
+
Please wait...
diff --git a/Flow.Launcher/Languages/ko.xaml b/Flow.Launcher/Languages/ko.xaml
index 9ae2e0195..9e8f9a73b 100644
--- a/Flow.Launcher/Languages/ko.xaml
+++ b/Flow.Launcher/Languages/ko.xaml
@@ -362,6 +362,7 @@
파일관리자 선택
+ Learn more
사용 중인 파일 관리자의 파일 위치를 지정하고, 필요한 경우 인수를 추가하세요. "%d"는 열고자 하는 디렉터리 경로를 나타내며, 폴더용 인수 필드 및 특정 디렉터리를 여는 명령어에서 사용됩니다. "%f"는 열고자 하는 파일 경로를 나타내며, 파일용 인수 필드 및 특정 파일을 여는 명령어에서 사용됩니다.
예를 들어, 파일 관리자가 totalcmd.exe /A c:\windows와 같은 명령어로 c:\windows 디렉터리를 연다면, 파일 관리자 경로는 totalcmd.exe가 되고, 폴더용 인수는 /A "%d"가 됩니다. QTTabBar와 같은 일부 파일 관리자는 경로만 전달하면 되는 경우가 있으므로, 이 경우에는 파일 관리자 경로에 "%d"를 입력하고 나머지 필드는 비워두세요.
파일관리자
@@ -369,6 +370,8 @@
파일관리자 경로
폴더경로 인수
파일경로 인수
+ The file manager '{0}' could not be located at '{1}'. Would you like to continue?
+ File Manager Path Error
기본 웹 브라우저
@@ -460,6 +463,14 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
1. Upload log file: {0}
2. Copy below exception message
+
+ File Manager Error
+
+ The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General.
+
+ Error
+ An error occurred while opening the folder. {0}
+
잠시 기다려주세요...
diff --git a/Flow.Launcher/Languages/nb.xaml b/Flow.Launcher/Languages/nb.xaml
index 58571a1c4..8d5ac7a94 100644
--- a/Flow.Launcher/Languages/nb.xaml
+++ b/Flow.Launcher/Languages/nb.xaml
@@ -371,6 +371,7 @@
Velg filbehandler
+ Learn more
Vennligst spesifiser filplasseringen til filbehandleren du bruker, og legg til argumenter etter behov. "%d" representerer katalogbanen som skal åpnes for, brukt av Arg for mappe-feltet og for kommandoer som åpner spesifikke kataloger. "%f" representerer filbanen som skal åpnes for, brukt av Arg for fil-feltet og for kommandoer som åpner spesifikke filer.
For eksempel, hvis filbehandleren bruker en kommando som "totalcmd.exe /A c:windows" for å åpne c:windows-katalogen, vil filbehandlingsbanen bli totalcmd.exe, og Arg For Folder vil være /A "%d". Enkelte filbehandlere som QTTabBar kan bare kreve at en bane oppgis, i dette tilfellet bruker du "%d" som filbehandlingsbane og lar resten av feltene stå tomme.
Filbehandler
@@ -378,6 +379,8 @@
Filbehandler sti
Arg for mappe
Arg for fil
+ The file manager '{0}' could not be located at '{1}'. Would you like to continue?
+ File Manager Path Error
Standard nettleser
@@ -469,6 +472,14 @@ Hvis du legger til et @-prefiks mens du legger inn en snarvei, samsvarer det med
1. Upload log file: {0}
2. Copy below exception message
+
+ File Manager Error
+
+ The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General.
+
+ Feil
+ An error occurred while opening the folder. {0}
+
Vennligst vent...
diff --git a/Flow.Launcher/Languages/nl.xaml b/Flow.Launcher/Languages/nl.xaml
index 70a58e322..0f6ad436d 100644
--- a/Flow.Launcher/Languages/nl.xaml
+++ b/Flow.Launcher/Languages/nl.xaml
@@ -371,6 +371,7 @@
Bestandsbeheerder selecteren
+ Learn more
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.
Bestandsbeheerder
@@ -378,6 +379,8 @@
Bestandsbeheerder pad
Arg voor map
Arg voor bestand
+ The file manager '{0}' could not be located at '{1}'. Would you like to continue?
+ File Manager Path Error
Standaard webbrowser
@@ -469,6 +472,14 @@ Als u een '@' voorvoegsel toevoegt tijdens het invoeren van een snelkoppeling, m
1. Upload log file: {0}
2. Copy below exception message
+
+ File Manager Error
+
+ The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General.
+
+ Error
+ An error occurred while opening the folder. {0}
+
Please wait...
diff --git a/Flow.Launcher/Languages/pl.xaml b/Flow.Launcher/Languages/pl.xaml
index 081c8e90e..1397afa25 100644
--- a/Flow.Launcher/Languages/pl.xaml
+++ b/Flow.Launcher/Languages/pl.xaml
@@ -371,6 +371,7 @@ Kliknij "nie", jeśli jest już zainstalowany. Zostaniesz wtedy popros
Wybierz menedżer plików
+ Learn more
Proszę określić lokalizację pliku menedżera plików, którego używasz i dodać argumenty według potrzeb. Symbol "%d" reprezentuje ścieżkę katalogu do otwarcia, używaną w polu Arg dla Folderu oraz dla poleceń otwierających konkretne katalogi. Symbol "%f" reprezentuje ścieżkę pliku do otwarcia, używaną w polu Arg dla Pliku oraz dla poleceń otwierających konkretne pliki.
Na przykład, jeśli menedżer plików używa polecenia takiego jak „totalcmd.exe /A c:\windows" do otwarcia katalogu c:\windows, Ścieżka Menedżera Plików będzie totalcmd.exe, a Argument dla Folderu będzie /A "%d". Niektóre menedżery plików, takie jak QTTabBar, mogą wymagać jedynie podania ścieżki; w takim przypadku użyj "%d" jako Ścieżki Menedżera Plików, a pozostałe pola pozostaw puste.
Menadżer plików
@@ -378,6 +379,8 @@ Kliknij "nie", jeśli jest już zainstalowany. Zostaniesz wtedy popros
Ścieżka menedżera plików
Arg dla folderu
Arg dla pliku
+ The file manager '{0}' could not be located at '{1}'. Would you like to continue?
+ File Manager Path Error
Domyślna przeglądarka
@@ -469,6 +472,14 @@ Jeśli dodasz prefiks '@' podczas wprowadzania skrótu, będzie on pasował do d
1. Prześlij plik dziennika: {0}
2. Skopiuj poniższą wiadomość wyjątku
+
+ File Manager Error
+
+ The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General.
+
+ Błąd
+ An error occurred while opening the folder. {0}
+
Proszę czekać...
diff --git a/Flow.Launcher/Languages/pt-br.xaml b/Flow.Launcher/Languages/pt-br.xaml
index bd74d1d5f..232134290 100644
--- a/Flow.Launcher/Languages/pt-br.xaml
+++ b/Flow.Launcher/Languages/pt-br.xaml
@@ -371,6 +371,7 @@
Selecione o Gerenciador de Arquivos
+ Learn more
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.
Gerenciador de Arquivos
@@ -378,6 +379,8 @@
Caminho do Gerenciador de Arquivos
Arg para Pasta
Arg para Arquivo
+ The file manager '{0}' could not be located at '{1}'. Would you like to continue?
+ File Manager Path Error
Navegador da Web Padrão
@@ -469,6 +472,14 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
1. Upload log file: {0}
2. Copy below exception message
+
+ File Manager Error
+
+ The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General.
+
+ Error
+ An error occurred while opening the folder. {0}
+
Por favor, aguarde...
diff --git a/Flow.Launcher/Languages/pt-pt.xaml b/Flow.Launcher/Languages/pt-pt.xaml
index cf7312956..f98fdf64b 100644
--- a/Flow.Launcher/Languages/pt-pt.xaml
+++ b/Flow.Launcher/Languages/pt-pt.xaml
@@ -369,6 +369,7 @@
Selecione o gestor de ficheiros
+ Saber mais
Por favor, especifique a localização do executável do seu gestor de ficheiros e adicione os argumentos necessários. "%d" representa o caminho do diretório a abrir, usado pelo argumento do campo Pasta e para comandos que abrem diretórios específicos. "%f" representa o caminho do ficheiro a abrir, usado pelo argumento do campo Ficheiro e para comandos que abrem ficheiros específicos.
Por exemplo, se o gestor de ficheiros utilizar o comando "totalcmd.exe /A c:\windows" para abrir o diretório c:\windows , o caminho para o gestor de ficheiros será totalcmd. exe e os argumentos para a Pasta serão /A "%d". Alguns gestores de ficheiros, como QTTabBar podem apenas exigir que especifique o caminho. Para estes, deve utilizar "%d" como caminho para o gestor de ficheiros e deixar o resto dos campos em branco.
Gestor de ficheiros
@@ -376,6 +377,8 @@
Caminho do gestor de ficheiros
Argumento para pasta
Argumento para ficheiro
+ Não foi possível encontrar o gestor de ficheiros '{0}' em '{1}'. Deseja continuar?
+ Erro no caminho do gestor de ficheiros
Navegador web padrão
@@ -467,6 +470,14 @@ Se adicionar o prefixo '@' durante a introdução do atalho, será utilizada qua
1. Carregue o ficheiro de registos: {0}
2. Copie a mensagem abaixo
+
+ Erro do gestor de ficheiros
+
+ Não foi possível encontrar o gestor de ficheiros. Verifique a definição 'Gestor de ficheiros personalizado' em Definições -> Geral.
+
+ Erro
+ Ocorreu um erro ao abrir a pasta: {0}
+
Por favor aguarde...
diff --git a/Flow.Launcher/Languages/ru.xaml b/Flow.Launcher/Languages/ru.xaml
index 69069c5ec..2a9b5c26b 100644
--- a/Flow.Launcher/Languages/ru.xaml
+++ b/Flow.Launcher/Languages/ru.xaml
@@ -371,6 +371,7 @@
Выбор менеджера файлов
+ Learn more
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.
Файловый менеджер
@@ -378,6 +379,8 @@
Путь к файловому менеджеру
Аргумент для папки
Аргумент для файла
+ The file manager '{0}' could not be located at '{1}'. Would you like to continue?
+ File Manager Path Error
Браузер по умолчанию
@@ -469,6 +472,14 @@
1. Upload log file: {0}
2. Copy below exception message
+
+ File Manager Error
+
+ The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General.
+
+ Ошибка
+ An error occurred while opening the folder. {0}
+
Пожалуйста, подождите...
diff --git a/Flow.Launcher/Languages/sk.xaml b/Flow.Launcher/Languages/sk.xaml
index 88ed1c9df..934b0747a 100644
--- a/Flow.Launcher/Languages/sk.xaml
+++ b/Flow.Launcher/Languages/sk.xaml
@@ -371,6 +371,7 @@
Vyberte správcu súborov
+ Viac informácií
Zadajte umiestnenie súboru správcu súborov, ktorý používate, a podľa potreby pridajte argumenty. "%d" predstavuje cestu k priečinku, ktorý sa má otvoriť, používa sa v poli Arg pre priečinok a pri príkazoch na otvorenie konkrétnych priečinkov. "%f" predstavuje cestu k súboru, ktorá sa má otvoriť a používa sa v poli Arg pre súbor a pri príkazoch na otvorenie konkrétnych súborov.
Napríklad, ak správca súborov používa príkaz ako "totalcmd.exe /A c:\windows" na otvorenie priečinka c:\windows, cesta správcu súborov bude totalcmd.exe a Arg pre priečinok bude /A "%d". Niektorí správcovia súborov, ako napríklad QTTabBar, môžu vyžadovať len zadanie cesty, v tomto prípade použite "%d" ako cestu správcu súborov a zvyšok súborov nechajte prázdny.
Správca súborov
@@ -378,6 +379,8 @@
Cesta k správcovi súborov
Arg. pre priečinok
Arg. pre súbor
+ Správca súborov '{0}' sa nenachádza na '{1}'. Chcete pokračovať?
+ Chyba v ceste k správcovi súborov
Predvolený webový prehliadač
@@ -445,7 +448,7 @@ Ak pri zadávaní skratky pred ňu pridáte "@", bude sa zhodovať s
Zrušiť
Resetovať
Odstrániť
- Aktualizovať
+ OK
Áno
Nie
Pozadie
@@ -469,6 +472,14 @@ Ak pri zadávaní skratky pred ňu pridáte "@", bude sa zhodovať s
1. Nahrajte súbor logu: {0}
2. Skopírujte nižšie uvedenú správu o výnimke
+
+ Chyba správcu súborov
+
+ Zadaný správca súborov sa nenašiel. Skontrolujte nastavenie vlastného správcu súborov v Nastavenia > Všeobecné.
+
+ Chyba
+ Počas otvárania priečinka sa vyskytla chyba. {0}
+
Čakajte, prosím...
diff --git a/Flow.Launcher/Languages/sr.xaml b/Flow.Launcher/Languages/sr.xaml
index 4b3e3bc0c..0d2c04513 100644
--- a/Flow.Launcher/Languages/sr.xaml
+++ b/Flow.Launcher/Languages/sr.xaml
@@ -371,6 +371,7 @@
Select File Manager
+ Learn more
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
@@ -378,6 +379,8 @@
File Manager Path
Arg For Folder
Arg For File
+ The file manager '{0}' could not be located at '{1}'. Would you like to continue?
+ File Manager Path Error
Default Web Browser
@@ -469,6 +472,14 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
1. Upload log file: {0}
2. Copy below exception message
+
+ File Manager Error
+
+ The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General.
+
+ Error
+ An error occurred while opening the folder. {0}
+
Please wait...
diff --git a/Flow.Launcher/Languages/tr.xaml b/Flow.Launcher/Languages/tr.xaml
index 665694ace..ab9aa31e6 100644
--- a/Flow.Launcher/Languages/tr.xaml
+++ b/Flow.Launcher/Languages/tr.xaml
@@ -371,6 +371,7 @@
Dosya Yöneticisi Seçenekleri
+ Learn more
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.
Dosya Yöneticisi
@@ -378,6 +379,8 @@
Dosya Yöneticisi Yolu
Klasör Açarken
Dosya Açarken
+ The file manager '{0}' could not be located at '{1}'. Would you like to continue?
+ File Manager Path Error
İnternet Tarayıcı Seçenekleri
@@ -467,6 +470,14 @@
1. Upload log file: {0}
2. Copy below exception message
+
+ File Manager Error
+
+ The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General.
+
+ Error
+ An error occurred while opening the folder. {0}
+
Lütfen bekleyin...
diff --git a/Flow.Launcher/Languages/uk-UA.xaml b/Flow.Launcher/Languages/uk-UA.xaml
index b3dc2cd16..f7cc7b0ed 100644
--- a/Flow.Launcher/Languages/uk-UA.xaml
+++ b/Flow.Launcher/Languages/uk-UA.xaml
@@ -371,6 +371,7 @@
Виберіть файловий менеджер
+ Learn more
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.
Файловий менеджер
@@ -378,6 +379,8 @@
Шлях до файлового менеджера
Аргумент для папки
Аргумент для файлу
+ The file manager '{0}' could not be located at '{1}'. Would you like to continue?
+ File Manager Path Error
Веб-браузер за замовчуванням
@@ -469,6 +472,14 @@
1. Upload log file: {0}
2. Copy below exception message
+
+ File Manager Error
+
+ The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General.
+
+ Помилка
+ An error occurred while opening the folder. {0}
+
Будь ласка, зачекайте...
diff --git a/Flow.Launcher/Languages/vi.xaml b/Flow.Launcher/Languages/vi.xaml
index b7b56213b..95e43e297 100644
--- a/Flow.Launcher/Languages/vi.xaml
+++ b/Flow.Launcher/Languages/vi.xaml
@@ -373,6 +373,7 @@
Chọn trình quản lý tệp
+ Learn more
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.
Trình quản lý ngày tháng
@@ -380,6 +381,8 @@
Đường dẫn quản lý tệp
Đối số cho thư mục
Đối số cho tệp
+ The file manager '{0}' could not be located at '{1}'. Would you like to continue?
+ File Manager Path Error
Trình duyệt web tiêu chuẩn
@@ -473,6 +476,14 @@
1. Upload log file: {0}
2. Copy below exception message
+
+ File Manager Error
+
+ The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General.
+
+ Lỗi
+ An error occurred while opening the folder. {0}
+
Cảnh báo nhỏ...
diff --git a/Flow.Launcher/Languages/zh-cn.xaml b/Flow.Launcher/Languages/zh-cn.xaml
index bd3142992..f6576070f 100644
--- a/Flow.Launcher/Languages/zh-cn.xaml
+++ b/Flow.Launcher/Languages/zh-cn.xaml
@@ -371,6 +371,7 @@
默认文件管理器
+ Learn more
请指定您使用的文件管理器的文件位置并根据需要添加参数。“%d”表示要打开的目录路径,由文件夹字段的参数和打开特定目录的命令使用。“%f”表示要打开的文件路径,由文件字段的参数和打开特定文件的命令使用。
例如,如果文件管理器使用诸如“totalcmd.exe /A c:\windows”之类的命令来打开 c:\windows 目录,则文件管理器路径将为 totalcmd.exe,文件夹参数将为 /A "%d"。某些文件管理器(如 QTTabBar)可能只需要提供路径,在本例中,使用“%d”作为文件管理器路径,其余字段留空。
文件管理器
@@ -378,6 +379,8 @@
文件管理器路径
文件夹路径参数
选中文件路径参数
+ The file manager '{0}' could not be located at '{1}'. Would you like to continue?
+ File Manager Path Error
默认浏览器
@@ -469,6 +472,14 @@
1. Upload log file: {0}
2. Copy below exception message
+
+ File Manager Error
+
+ The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General.
+
+ 错误
+ An error occurred while opening the folder. {0}
+
请稍等...
diff --git a/Flow.Launcher/Languages/zh-tw.xaml b/Flow.Launcher/Languages/zh-tw.xaml
index 1a71ae135..42810f590 100644
--- a/Flow.Launcher/Languages/zh-tw.xaml
+++ b/Flow.Launcher/Languages/zh-tw.xaml
@@ -371,6 +371,7 @@
選擇檔案管理器
+ Learn more
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.
檔案管理器
@@ -378,6 +379,8 @@
檔案管理器路徑
資料夾參數
檔案參數
+ The file manager '{0}' could not be located at '{1}'. Would you like to continue?
+ File Manager Path Error
預設瀏覽器
@@ -469,6 +472,14 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
1. Upload log file: {0}
2. Copy below exception message
+
+ File Manager Error
+
+ The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General.
+
+ Error
+ An error occurred while opening the folder. {0}
+
請稍後...
diff --git a/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.ja-JP.resx b/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.ja-JP.resx
index 2e2de0681..91be8a392 100644
--- a/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.ja-JP.resx
+++ b/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.ja-JP.resx
@@ -456,7 +456,7 @@
Area Personalization
-
+
The command to direct start a setting
@@ -1117,7 +1117,7 @@
Area Control Panel (legacy settings)
-
+
password.cpl
@@ -1572,7 +1572,7 @@
Area Control Panel (legacy settings)
-
+
Means The "Windows Version"
From 383c0aeffc9afc1351f3c008d62aa0915ddc0da4 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 23 May 2025 13:41:59 +0800
Subject: [PATCH 1305/1697] Improve code quality
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 209 +++++++++++++++++
.../ViewModel/PluginStoreItemViewModel.cs | 221 +-----------------
Flow.Launcher/ViewModel/PluginViewModel.cs | 2 +-
3 files changed, 213 insertions(+), 219 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index aae8dd764..5b14ad0b7 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -6,6 +6,7 @@ using System.Linq;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
+using System.Windows;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Core.ExternalPlugins;
using Flow.Launcher.Infrastructure;
@@ -24,6 +25,8 @@ namespace Flow.Launcher.Core.Plugin
{
private static readonly string ClassName = nameof(PluginManager);
+ private static readonly Settings FlowSettings = Ioc.Default.GetRequiredService();
+
private static IEnumerable _contextMenuPlugins;
private static IEnumerable _homePlugins;
@@ -547,6 +550,177 @@ namespace Flow.Launcher.Core.Plugin
await UninstallPluginAsync(plugin, removePluginFromSettings, removePluginSettings, true);
}
+ public static async Task InstallPluginAndCheckRestartAsync(UserPlugin newPlugin)
+ {
+ if (API.ShowMsgBox(
+ string.Format(
+ API.GetTranslation("InstallPromptSubtitle"),
+ newPlugin.Name, newPlugin.Author, Environment.NewLine),
+ API.GetTranslation("InstallPromptTitle"),
+ button: MessageBoxButton.YesNo) != MessageBoxResult.Yes) return;
+
+ try
+ {
+ // at minimum should provide a name, but handle plugin that is not downloaded from plugins manifest and is a url download
+ var downloadFilename = string.IsNullOrEmpty(newPlugin.Version)
+ ? $"{newPlugin.Name}-{Guid.NewGuid()}.zip"
+ : $"{newPlugin.Name}-{newPlugin.Version}.zip";
+
+ var filePath = Path.Combine(Path.GetTempPath(), downloadFilename);
+
+ using var cts = new CancellationTokenSource();
+
+ if (!newPlugin.IsFromLocalInstallPath)
+ {
+ await DownloadFileAsync(
+ $"{API.GetTranslation("DownloadingPlugin")} {newPlugin.Name}",
+ newPlugin.UrlDownload, filePath, cts);
+ }
+ else
+ {
+ filePath = newPlugin.LocalInstallPath;
+ }
+
+ // check if user cancelled download before installing plugin
+ if (cts.IsCancellationRequested)
+ {
+ return;
+ }
+ else
+ {
+ if (!File.Exists(filePath))
+ {
+ throw new FileNotFoundException($"Plugin {newPlugin.ID} zip file not found at {filePath}", filePath);
+ }
+
+ API.InstallPlugin(newPlugin, filePath);
+
+ if (!newPlugin.IsFromLocalInstallPath)
+ {
+ File.Delete(filePath);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ API.LogException(ClassName, "Failed to install plugin", e);
+ API.ShowMsgError(API.GetTranslation("ErrorInstallingPlugin"));
+ return; // don’t restart on failure
+ }
+
+ if (FlowSettings.AutoRestartAfterChanging)
+ {
+ API.RestartApp();
+ }
+ else
+ {
+ API.ShowMsg(
+ API.GetTranslation("installbtn"),
+ string.Format(
+ API.GetTranslation(
+ "InstallSuccessNoRestart"),
+ newPlugin.Name));
+ }
+ }
+
+ public static async Task UninstallPluginAndCheckRestartAsync(PluginMetadata oldPlugin)
+ {
+ if (API.ShowMsgBox(
+ string.Format(
+ API.GetTranslation("UninstallPromptSubtitle"),
+ oldPlugin.Name, oldPlugin.Author, Environment.NewLine),
+ API.GetTranslation("UninstallPromptTitle"),
+ button: MessageBoxButton.YesNo) != MessageBoxResult.Yes) return;
+
+ var removePluginSettings = API.ShowMsgBox(
+ API.GetTranslation("KeepPluginSettingsSubtitle"),
+ API.GetTranslation("KeepPluginSettingsTitle"),
+ button: MessageBoxButton.YesNo) == MessageBoxResult.No;
+
+ try
+ {
+ await API.UninstallPluginAsync(oldPlugin, removePluginSettings);
+ }
+ catch (Exception e)
+ {
+ API.LogException(ClassName, "Failed to uninstall plugin", e);
+ API.ShowMsgError(API.GetTranslation("ErrorUninstallingPlugin"));
+ return; // don’t restart on failure
+ }
+
+ if (FlowSettings.AutoRestartAfterChanging)
+ {
+ API.RestartApp();
+ }
+ else
+ {
+ API.ShowMsg(
+ API.GetTranslation("uninstallbtn"),
+ string.Format(
+ API.GetTranslation(
+ "UninstallSuccessNoRestart"),
+ oldPlugin.Name));
+ }
+ }
+
+ public static async Task UpdatePluginAndCheckRestartAsync(UserPlugin newPlugin, PluginMetadata oldPlugin)
+ {
+ if (API.ShowMsgBox(
+ string.Format(
+ API.GetTranslation("UpdatePromptSubtitle"),
+ oldPlugin.Name, oldPlugin.Author, Environment.NewLine),
+ API.GetTranslation("UpdatePromptTitle"),
+ button: MessageBoxButton.YesNo) != MessageBoxResult.Yes) return;
+
+ try
+ {
+ var filePath = Path.Combine(Path.GetTempPath(), $"{newPlugin.Name}-{newPlugin.Version}.zip");
+
+ using var cts = new CancellationTokenSource();
+
+ if (!newPlugin.IsFromLocalInstallPath)
+ {
+ await DownloadFileAsync(
+ $"{API.GetTranslation("DownloadingPlugin")} {newPlugin.Name}",
+ newPlugin.UrlDownload, filePath, cts);
+ }
+ else
+ {
+ filePath = newPlugin.LocalInstallPath;
+ }
+
+ // check if user cancelled download before installing plugin
+ if (cts.IsCancellationRequested)
+ {
+ return;
+ }
+ else
+ {
+ await API.UpdatePluginAsync(oldPlugin, newPlugin, filePath);
+ }
+ }
+ catch (Exception e)
+ {
+ API.LogException(ClassName, "Failed to update plugin", e);
+ API.ShowMsgError(API.GetTranslation("ErrorUpdatingPlugin"));
+ return; // don’t restart on failure
+ }
+
+ if (FlowSettings.AutoRestartAfterChanging)
+ {
+ API.RestartApp();
+ }
+ else
+ {
+ API.ShowMsg(
+ API.GetTranslation("updatebtn"),
+ string.Format(
+ API.GetTranslation(
+ "UpdateSuccessNoRestart"),
+ newPlugin.Name));
+ }
+ }
+
#endregion
#region Internal functions
@@ -694,6 +868,41 @@ namespace Flow.Launcher.Core.Plugin
}
}
+ internal static async Task DownloadFileAsync(string prgBoxTitle, string downloadUrl, string filePath, CancellationTokenSource cts, bool deleteFile = true, bool showProgress = true)
+ {
+ if (deleteFile && File.Exists(filePath))
+ File.Delete(filePath);
+
+ if (showProgress)
+ {
+ var exceptionHappened = false;
+ await 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 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 API.HttpDownloadAsync(downloadUrl, filePath, token: cts.Token).ConfigureAwait(false);
+ }
+ else
+ {
+ await API.HttpDownloadAsync(downloadUrl, filePath, token: cts.Token).ConfigureAwait(false);
+ }
+ }
+
#endregion
}
}
diff --git a/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs b/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs
index 6b2cf6eed..a504b7a05 100644
--- a/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs
@@ -1,12 +1,7 @@
using System;
-using System.IO;
-using System.Threading;
using System.Threading.Tasks;
-using System.Windows;
-using CommunityToolkit.Mvvm.DependencyInjection;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.Core.Plugin;
-using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Version = SemanticVersioning.Version;
@@ -14,10 +9,6 @@ namespace Flow.Launcher.ViewModel
{
public partial class PluginStoreItemViewModel : BaseModel
{
- private static readonly string ClassName = nameof(PluginStoreItemViewModel);
-
- private static readonly Settings Settings = Ioc.Default.GetRequiredService();
-
private readonly UserPlugin _newPlugin;
private readonly PluginPair _oldPluginPair;
@@ -74,223 +65,17 @@ namespace Flow.Launcher.ViewModel
switch (action)
{
case "install":
- await InstallPluginAsync(_newPlugin);
+ await PluginManager.InstallPluginAndCheckRestartAsync(_newPlugin);
break;
case "uninstall":
- await UninstallPluginAsync(_oldPluginPair.Metadata);
+ await PluginManager.UninstallPluginAndCheckRestartAsync(_oldPluginPair.Metadata);
break;
case "update":
- await UpdatePluginAsync(_newPlugin, _oldPluginPair.Metadata);
+ await PluginManager.UpdatePluginAndCheckRestartAsync(_newPlugin, _oldPluginPair.Metadata);
break;
default:
break;
}
}
-
- internal static async Task InstallPluginAsync(UserPlugin newPlugin)
- {
- if (App.API.ShowMsgBox(
- string.Format(
- App.API.GetTranslation("InstallPromptSubtitle"),
- newPlugin.Name, newPlugin.Author, Environment.NewLine),
- App.API.GetTranslation("InstallPromptTitle"),
- button: MessageBoxButton.YesNo) != MessageBoxResult.Yes) return;
-
- try
- {
- // at minimum should provide a name, but handle plugin that is not downloaded from plugins manifest and is a url download
- var downloadFilename = string.IsNullOrEmpty(newPlugin.Version)
- ? $"{newPlugin.Name}-{Guid.NewGuid()}.zip"
- : $"{newPlugin.Name}-{newPlugin.Version}.zip";
-
- var filePath = Path.Combine(Path.GetTempPath(), downloadFilename);
-
- using var cts = new CancellationTokenSource();
-
- if (!newPlugin.IsFromLocalInstallPath)
- {
- await DownloadFileAsync(
- $"{App.API.GetTranslation("DownloadingPlugin")} {newPlugin.Name}",
- newPlugin.UrlDownload, filePath, cts);
- }
- else
- {
- filePath = newPlugin.LocalInstallPath;
- }
-
- // check if user cancelled download before installing plugin
- if (cts.IsCancellationRequested)
- {
- return;
- }
- else
- {
- if (!File.Exists(filePath))
- {
- throw new FileNotFoundException($"Plugin {newPlugin.ID} zip file not found at {filePath}", filePath);
- }
-
- App.API.InstallPlugin(newPlugin, filePath);
-
- if (!newPlugin.IsFromLocalInstallPath)
- {
- File.Delete(filePath);
- }
- }
- }
- catch (Exception e)
- {
- App.API.LogException(ClassName, "Failed to install plugin", e);
- App.API.ShowMsgError(App.API.GetTranslation("ErrorInstallingPlugin"));
- return; // don’t restart on failure
- }
-
- if (Settings.AutoRestartAfterChanging)
- {
- App.API.RestartApp();
- }
- else
- {
- App.API.ShowMsg(
- App.API.GetTranslation("installbtn"),
- string.Format(
- App.API.GetTranslation(
- "InstallSuccessNoRestart"),
- newPlugin.Name));
- }
- }
-
- internal static async Task UninstallPluginAsync(PluginMetadata oldPlugin)
- {
- if (App.API.ShowMsgBox(
- string.Format(
- App.API.GetTranslation("UninstallPromptSubtitle"),
- oldPlugin.Name, oldPlugin.Author, Environment.NewLine),
- App.API.GetTranslation("UninstallPromptTitle"),
- button: MessageBoxButton.YesNo) != MessageBoxResult.Yes) return;
-
- var removePluginSettings = App.API.ShowMsgBox(
- App.API.GetTranslation("KeepPluginSettingsSubtitle"),
- App.API.GetTranslation("KeepPluginSettingsTitle"),
- button: MessageBoxButton.YesNo) == MessageBoxResult.No;
-
- try
- {
- await App.API.UninstallPluginAsync(oldPlugin, removePluginSettings);
- }
- catch (Exception e)
- {
- App.API.LogException(ClassName, "Failed to uninstall plugin", e);
- App.API.ShowMsgError(App.API.GetTranslation("ErrorUninstallingPlugin"));
- return; // don’t restart on failure
- }
-
- if (Settings.AutoRestartAfterChanging)
- {
- App.API.RestartApp();
- }
- else
- {
- App.API.ShowMsg(
- App.API.GetTranslation("uninstallbtn"),
- string.Format(
- App.API.GetTranslation(
- "UninstallSuccessNoRestart"),
- oldPlugin.Name));
- }
- }
-
- internal static async Task UpdatePluginAsync(UserPlugin newPlugin, PluginMetadata oldPlugin)
- {
- if (App.API.ShowMsgBox(
- string.Format(
- App.API.GetTranslation("UpdatePromptSubtitle"),
- oldPlugin.Name, oldPlugin.Author, Environment.NewLine),
- App.API.GetTranslation("UpdatePromptTitle"),
- button: MessageBoxButton.YesNo) != MessageBoxResult.Yes) return;
-
- try
- {
- var filePath = Path.Combine(Path.GetTempPath(), $"{newPlugin.Name}-{newPlugin.Version}.zip");
-
- using var cts = new CancellationTokenSource();
-
- if (!newPlugin.IsFromLocalInstallPath)
- {
- await DownloadFileAsync(
- $"{App.API.GetTranslation("DownloadingPlugin")} {newPlugin.Name}",
- newPlugin.UrlDownload, filePath, cts);
- }
- else
- {
- filePath = newPlugin.LocalInstallPath;
- }
-
- // check if user cancelled download before installing plugin
- if (cts.IsCancellationRequested)
- {
- return;
- }
- else
- {
- await App.API.UpdatePluginAsync(oldPlugin, newPlugin, filePath);
- }
- }
- catch (Exception e)
- {
- App.API.LogException(ClassName, "Failed to update plugin", e);
- App.API.ShowMsgError(App.API.GetTranslation("ErrorUpdatingPlugin"));
- return; // don’t restart on failure
- }
-
- if (Settings.AutoRestartAfterChanging)
- {
- App.API.RestartApp();
- }
- else
- {
- App.API.ShowMsg(
- App.API.GetTranslation("updatebtn"),
- string.Format(
- App.API.GetTranslation(
- "UpdateSuccessNoRestart"),
- newPlugin.Name));
- }
- }
-
- private static async Task DownloadFileAsync(string prgBoxTitle, string downloadUrl, string filePath, CancellationTokenSource cts, bool deleteFile = true, bool showProgress = true)
- {
- if (deleteFile && File.Exists(filePath))
- File.Delete(filePath);
-
- if (showProgress)
- {
- var exceptionHappened = false;
- await App.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 App.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 App.API.HttpDownloadAsync(downloadUrl, filePath, token: cts.Token).ConfigureAwait(false);
- }
- else
- {
- await App.API.HttpDownloadAsync(downloadUrl, filePath, token: cts.Token).ConfigureAwait(false);
- }
- }
}
}
diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs
index bda05a02d..f902fb037 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -172,7 +172,7 @@ namespace Flow.Launcher.ViewModel
[RelayCommand]
private async Task OpenDeletePluginWindowAsync()
{
- await PluginStoreItemViewModel.UninstallPluginAsync(PluginPair.Metadata);
+ await PluginManager.UninstallPluginAndCheckRestartAsync(PluginPair.Metadata);
}
[RelayCommand]
From 90ad72ca30ca7e99e3e84c4cac4e507f91b47a4c Mon Sep 17 00:00:00 2001
From: 01Dri
Date: Fri, 23 May 2025 16:33:47 -0300
Subject: [PATCH 1306/1697] Diff Time in Created At and LastModifiedAt
---
.../Views/PreviewPanel.xaml.cs | 47 ++++++++++++++-----
1 file changed, 34 insertions(+), 13 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
index aaf1efdc1..1981a8b0e 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
@@ -1,4 +1,5 @@
-using System.ComponentModel;
+using System;
+using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Runtime.CompilerServices;
@@ -65,22 +66,22 @@ public partial class PreviewPanel : UserControl, INotifyPropertyChanged
if (Settings.ShowCreatedDateInPreviewPanel)
{
- CreatedAt = File
- .GetCreationTime(filePath)
- .ToString(
- $"{Settings.PreviewPanelDateFormat} {Settings.PreviewPanelTimeFormat}",
- CultureInfo.CurrentCulture
- );
+ DateTime createdDate = File.GetCreationTime(filePath);
+ string formattedDate = createdDate.ToString(
+ $"{Settings.PreviewPanelDateFormat} {Settings.PreviewPanelTimeFormat}",
+ CultureInfo.CurrentCulture
+ );
+ CreatedAt = $"{GetDiffTimeString(createdDate)} - {formattedDate}";
}
if (Settings.ShowModifiedDateInPreviewPanel)
{
- LastModifiedAt = File
- .GetLastWriteTime(filePath)
- .ToString(
- $"{Settings.PreviewPanelDateFormat} {Settings.PreviewPanelTimeFormat}",
- CultureInfo.CurrentCulture
- );
+ DateTime lastModifiedDate = File.GetLastWriteTime(filePath);
+ string formattedDate = lastModifiedDate.ToString(
+ $"{Settings.PreviewPanelDateFormat} {Settings.PreviewPanelTimeFormat}",
+ CultureInfo.CurrentCulture
+ );
+ LastModifiedAt = $"{GetDiffTimeString(lastModifiedDate)} - {formattedDate}";
}
_ = LoadImageAsync();
@@ -90,7 +91,27 @@ public partial class PreviewPanel : UserControl, INotifyPropertyChanged
{
PreviewImage = await Main.Context.API.LoadImageAsync(FilePath, true).ConfigureAwait(false);
}
+
+ private string GetDiffTimeString(DateTime fileDateTime)
+ {
+ DateTime now = DateTime.Now;
+ TimeSpan difference = now - fileDateTime;
+ if (difference.TotalDays < 1)
+ return "Today";
+ if (difference.TotalDays < 30)
+ return $"{(int)difference.TotalDays} days ago";
+
+ int monthsDiff = (now.Year - fileDateTime.Year) * 12 + now.Month - fileDateTime.Month;
+ if (monthsDiff < 12)
+ return monthsDiff == 1 ? "1 month ago" : $"{monthsDiff} months ago";
+
+ int yearsDiff = now.Year - fileDateTime.Year;
+ if (now.Month < fileDateTime.Month || (now.Month == fileDateTime.Month && now.Day < fileDateTime.Day))
+ yearsDiff--;
+
+ return yearsDiff == 1 ? "1 year ago" : $"{yearsDiff} years ago";
+ }
public event PropertyChangedEventHandler? PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
From 35e71c6f510256bdad0692919cdbfa1578d5ee87 Mon Sep 17 00:00:00 2001
From: 01Dri
Date: Sat, 24 May 2025 00:12:56 -0300
Subject: [PATCH 1307/1697] Relative Date checkbox
---
.../Flow.Launcher.Plugin.Explorer/Languages/en.xaml | 3 +++
.../Languages/pt-br.xaml | 5 +++--
Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs | 3 +++
.../ViewModels/SettingsViewModel.cs | 12 ++++++++++++
.../Views/ExplorerSettings.xaml | 5 +++++
.../Views/PreviewPanel.xaml.cs | 11 ++++++++---
6 files changed, 34 insertions(+), 5 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
index 79f8a5848..6680aacff 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
@@ -33,6 +33,7 @@
Size
Date Created
Date Modified
+ Relative Date
Display File Info
Date and time format
Sort Option:
@@ -125,6 +126,8 @@
Use '>' to search in this directory, '*' to search for file extensions or '>*' to combine both searches.
+
+
Failed to load Everything SDK
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-br.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-br.xaml
index 2754a5a99..59770a29d 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-br.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-br.xaml
@@ -29,8 +29,9 @@
Everything Setting
Preview Panel
Tamanho
- Date Created
- Date Modified
+ Data Criação
+ Data Modificação
+ Data Relativa
Display File Info
Date and time format
Sort Option:
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
index 3d30bcf29..0a91c024c 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
@@ -66,6 +66,9 @@ namespace Flow.Launcher.Plugin.Explorer
public bool ShowCreatedDateInPreviewPanel { get; set; } = true;
public bool ShowModifiedDateInPreviewPanel { get; set; } = true;
+
+ public bool ShowRelativeDateInPreviewPanel { get; set; } = true;
+
public string PreviewPanelDateFormat { get; set; } = "yyyy-MM-dd";
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
index cf9ebd33f..baa2c6c28 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
@@ -169,6 +169,18 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
}
}
+ public bool ShowRelativeDateInPreviewPanel
+ {
+ get => Settings.ShowRelativeDateInPreviewPanel;
+ set
+ {
+ Settings.ShowRelativeDateInPreviewPanel = value;
+ OnPropertyChanged();
+ OnPropertyChanged(nameof(ShowPreviewPanelDateTimeChoices));
+ OnPropertyChanged(nameof(PreviewPanelDateTimeChoicesVisibility));
+ }
+ }
+
public string PreviewPanelDateFormat
{
get => Settings.PreviewPanelDateFormat;
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
index e5999da41..c16dc4f51 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
@@ -505,6 +505,11 @@
Margin="{StaticResource SettingPanelItemLeftTopBottomMargin}"
Content="{DynamicResource plugin_explorer_previewpanel_display_file_modification_checkbox}"
IsChecked="{Binding ShowModifiedDateInPreviewPanel}" />
+
+
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
index 1981a8b0e..aa5ba6cc7 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
@@ -71,7 +71,10 @@ public partial class PreviewPanel : UserControl, INotifyPropertyChanged
$"{Settings.PreviewPanelDateFormat} {Settings.PreviewPanelTimeFormat}",
CultureInfo.CurrentCulture
);
- CreatedAt = $"{GetDiffTimeString(createdDate)} - {formattedDate}";
+
+ string result = formattedDate;
+ if (Settings.ShowRelativeDateInPreviewPanel) result = $"{GetFileAge(createdDate)} - {formattedDate}";
+ CreatedAt = result;
}
if (Settings.ShowModifiedDateInPreviewPanel)
@@ -81,7 +84,9 @@ public partial class PreviewPanel : UserControl, INotifyPropertyChanged
$"{Settings.PreviewPanelDateFormat} {Settings.PreviewPanelTimeFormat}",
CultureInfo.CurrentCulture
);
- LastModifiedAt = $"{GetDiffTimeString(lastModifiedDate)} - {formattedDate}";
+ string result = formattedDate;
+ if (Settings.ShowRelativeDateInPreviewPanel) result = $"{GetFileAge(lastModifiedDate)} - {formattedDate}";
+ LastModifiedAt = result;
}
_ = LoadImageAsync();
@@ -92,7 +97,7 @@ public partial class PreviewPanel : UserControl, INotifyPropertyChanged
PreviewImage = await Main.Context.API.LoadImageAsync(FilePath, true).ConfigureAwait(false);
}
- private string GetDiffTimeString(DateTime fileDateTime)
+ private string GetFileAge(DateTime fileDateTime)
{
DateTime now = DateTime.Now;
TimeSpan difference = now - fileDateTime;
From 02ddcaa0642a123ee1ac7caf747783651d4fc2f5 Mon Sep 17 00:00:00 2001
From: 01Dri
Date: Sat, 24 May 2025 00:15:08 -0300
Subject: [PATCH 1308/1697] Function name changed to GetRelativeDate
---
.../Views/PreviewPanel.xaml.cs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
index aa5ba6cc7..05dfd66f3 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
@@ -73,7 +73,7 @@ public partial class PreviewPanel : UserControl, INotifyPropertyChanged
);
string result = formattedDate;
- if (Settings.ShowRelativeDateInPreviewPanel) result = $"{GetFileAge(createdDate)} - {formattedDate}";
+ if (Settings.ShowRelativeDateInPreviewPanel) result = $"{GetRelativeDate(createdDate)} - {formattedDate}";
CreatedAt = result;
}
@@ -85,7 +85,7 @@ public partial class PreviewPanel : UserControl, INotifyPropertyChanged
CultureInfo.CurrentCulture
);
string result = formattedDate;
- if (Settings.ShowRelativeDateInPreviewPanel) result = $"{GetFileAge(lastModifiedDate)} - {formattedDate}";
+ if (Settings.ShowRelativeDateInPreviewPanel) result = $"{GetRelativeDate(lastModifiedDate)} - {formattedDate}";
LastModifiedAt = result;
}
@@ -97,7 +97,7 @@ public partial class PreviewPanel : UserControl, INotifyPropertyChanged
PreviewImage = await Main.Context.API.LoadImageAsync(FilePath, true).ConfigureAwait(false);
}
- private string GetFileAge(DateTime fileDateTime)
+ private string GetRelativeDate(DateTime fileDateTime)
{
DateTime now = DateTime.Now;
TimeSpan difference = now - fileDateTime;
From a711ce4ec793158c6586ec70e5e0cd913c77319b Mon Sep 17 00:00:00 2001
From: 01Dri
Date: Sat, 24 May 2025 01:10:12 -0300
Subject: [PATCH 1309/1697] Translate pt br
---
Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-br.xaml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-br.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-br.xaml
index 59770a29d..3ab958506 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-br.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-br.xaml
@@ -29,8 +29,8 @@
Everything Setting
Preview Panel
Tamanho
- Data Criação
- Data Modificação
+ Data de Criação
+ Data de Modificação
Data Relativa
Display File Info
Date and time format
From b2f5713386d4a8a702c91b461f25de1598865776 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 24 May 2025 13:10:25 +0800
Subject: [PATCH 1310/1697] =?UTF-8?q?Fix=20crash=20on=20=C3=9732=20devices?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../NativeMethods.txt | 2 +-
.../PInvokeExtensions.cs | 26 ++++++++++++++++---
Flow.Launcher.Infrastructure/Win32Helper.cs | 6 ++---
3 files changed, 27 insertions(+), 7 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/NativeMethods.txt b/Flow.Launcher.Infrastructure/NativeMethods.txt
index 0e50420b0..c01532414 100644
--- a/Flow.Launcher.Infrastructure/NativeMethods.txt
+++ b/Flow.Launcher.Infrastructure/NativeMethods.txt
@@ -22,7 +22,7 @@ SystemParametersInfo
SetForegroundWindow
-GetWindowLong
+WINDOW_LONG_PTR_INDEX
GetForegroundWindow
GetDesktopWindow
GetShellWindow
diff --git a/Flow.Launcher.Infrastructure/PInvokeExtensions.cs b/Flow.Launcher.Infrastructure/PInvokeExtensions.cs
index 1a72ab7a6..18b992043 100644
--- a/Flow.Launcher.Infrastructure/PInvokeExtensions.cs
+++ b/Flow.Launcher.Infrastructure/PInvokeExtensions.cs
@@ -4,14 +4,16 @@ using Windows.Win32.UI.WindowsAndMessaging;
namespace Windows.Win32;
-// Edited from: https://github.com/files-community/Files
internal static partial class PInvoke
{
+ // SetWindowLong
+ // Edited from: https://github.com/files-community/Files
+
[DllImport("User32", EntryPoint = "SetWindowLongW", ExactSpelling = true)]
- static extern int _SetWindowLong(HWND hWnd, int nIndex, int dwNewLong);
+ private static extern int _SetWindowLong(HWND hWnd, int nIndex, int dwNewLong);
[DllImport("User32", EntryPoint = "SetWindowLongPtrW", ExactSpelling = true)]
- static extern nint _SetWindowLongPtr(HWND hWnd, int nIndex, nint dwNewLong);
+ private static extern nint _SetWindowLongPtr(HWND hWnd, int nIndex, nint dwNewLong);
// NOTE:
// CsWin32 doesn't generate SetWindowLong on other than x86 and vice versa.
@@ -22,4 +24,22 @@ internal static partial class PInvoke
? _SetWindowLong(hWnd, (int)nIndex, (int)dwNewLong)
: _SetWindowLongPtr(hWnd, (int)nIndex, dwNewLong);
}
+
+ // GetWindowLong
+
+ [DllImport("User32", EntryPoint = "GetWindowLongW", ExactSpelling = true)]
+ private static extern int _GetWindowLong(HWND hWnd, int nIndex);
+
+ [DllImport("User32", EntryPoint = "GetWindowLongPtrW", ExactSpelling = true)]
+ private static extern nint _GetWindowLongPtr(HWND hWnd, int nIndex);
+
+ // NOTE:
+ // CsWin32 doesn't generate GetWindowLong on other than x86 and vice versa.
+ // For more info, visit https://github.com/microsoft/CsWin32/issues/882
+ public static unsafe nint GetWindowLongPtr(HWND hWnd, WINDOW_LONG_PTR_INDEX nIndex)
+ {
+ return sizeof(nint) is 4
+ ? _GetWindowLong(hWnd, (int)nIndex)
+ : _GetWindowLongPtr(hWnd, (int)nIndex);
+ }
}
diff --git a/Flow.Launcher.Infrastructure/Win32Helper.cs b/Flow.Launcher.Infrastructure/Win32Helper.cs
index 783ade14e..dad5f2f93 100644
--- a/Flow.Launcher.Infrastructure/Win32Helper.cs
+++ b/Flow.Launcher.Infrastructure/Win32Helper.cs
@@ -192,9 +192,9 @@ namespace Flow.Launcher.Infrastructure
SetWindowStyle(hwnd, WINDOW_LONG_PTR_INDEX.GWL_STYLE, style);
}
- private static int GetWindowStyle(HWND hWnd, WINDOW_LONG_PTR_INDEX nIndex)
+ private static nint GetWindowStyle(HWND hWnd, WINDOW_LONG_PTR_INDEX nIndex)
{
- var style = PInvoke.GetWindowLong(hWnd, nIndex);
+ var style = PInvoke.GetWindowLongPtr(hWnd, nIndex);
if (style == 0 && Marshal.GetLastPInvokeError() != 0)
{
throw new Win32Exception(Marshal.GetLastPInvokeError());
@@ -202,7 +202,7 @@ namespace Flow.Launcher.Infrastructure
return style;
}
- private static nint SetWindowStyle(HWND hWnd, WINDOW_LONG_PTR_INDEX nIndex, int dwNewLong)
+ private static nint SetWindowStyle(HWND hWnd, WINDOW_LONG_PTR_INDEX nIndex, nint dwNewLong)
{
PInvoke.SetLastError(WIN32_ERROR.NO_ERROR); // Clear any existing error
From f6103b1105d9c741c87ed0f954622c271a87620a Mon Sep 17 00:00:00 2001
From: 01Dri
Date: Sat, 24 May 2025 03:16:03 -0300
Subject: [PATCH 1311/1697] Relative Date -> File Age
---
Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml | 2 +-
Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-br.xaml | 2 +-
Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs | 2 +-
.../ViewModels/SettingsViewModel.cs | 6 +++---
.../Views/ExplorerSettings.xaml | 4 ++--
.../Views/PreviewPanel.xaml.cs | 4 ++--
6 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
index 6680aacff..aa86d96cf 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
@@ -33,7 +33,7 @@
Size
Date Created
Date Modified
- Relative Date
+ File Age
Display File Info
Date and time format
Sort Option:
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-br.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-br.xaml
index 3ab958506..ca7d9b48e 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-br.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-br.xaml
@@ -31,7 +31,7 @@
Tamanho
Data de Criação
Data de Modificação
- Data Relativa
+ Idade do Arquivo
Display File Info
Date and time format
Sort Option:
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
index 0a91c024c..158cf0347 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
@@ -67,7 +67,7 @@ namespace Flow.Launcher.Plugin.Explorer
public bool ShowModifiedDateInPreviewPanel { get; set; } = true;
- public bool ShowRelativeDateInPreviewPanel { get; set; } = true;
+ public bool ShowFileAgeInPreviewPanel { get; set; } = true;
public string PreviewPanelDateFormat { get; set; } = "yyyy-MM-dd";
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
index baa2c6c28..fb33dacab 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
@@ -169,12 +169,12 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
}
}
- public bool ShowRelativeDateInPreviewPanel
+ public bool ShowFileAgeInPreviewPanel
{
- get => Settings.ShowRelativeDateInPreviewPanel;
+ get => Settings.ShowFileAgeInPreviewPanel;
set
{
- Settings.ShowRelativeDateInPreviewPanel = value;
+ Settings.ShowFileAgeInPreviewPanel = value;
OnPropertyChanged();
OnPropertyChanged(nameof(ShowPreviewPanelDateTimeChoices));
OnPropertyChanged(nameof(PreviewPanelDateTimeChoicesVisibility));
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
index c16dc4f51..4302e721a 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
@@ -508,8 +508,8 @@
+ Content="{DynamicResource plugin_explorer_previewpanel_display_file_age_checkbox}"
+ IsChecked="{Binding ShowFileAgeInPreviewPanel}" />
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
index 05dfd66f3..801510eb7 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
@@ -73,7 +73,7 @@ public partial class PreviewPanel : UserControl, INotifyPropertyChanged
);
string result = formattedDate;
- if (Settings.ShowRelativeDateInPreviewPanel) result = $"{GetRelativeDate(createdDate)} - {formattedDate}";
+ if (Settings.ShowFileAgeInPreviewPanel) result = $"{GetRelativeDate(createdDate)} - {formattedDate}";
CreatedAt = result;
}
@@ -85,7 +85,7 @@ public partial class PreviewPanel : UserControl, INotifyPropertyChanged
CultureInfo.CurrentCulture
);
string result = formattedDate;
- if (Settings.ShowRelativeDateInPreviewPanel) result = $"{GetRelativeDate(lastModifiedDate)} - {formattedDate}";
+ if (Settings.ShowFileAgeInPreviewPanel) result = $"{GetRelativeDate(lastModifiedDate)} - {formattedDate}";
LastModifiedAt = result;
}
From d726455b047c380179243ff85ee132e7d601ba0c Mon Sep 17 00:00:00 2001
From: 01Dri
Date: Sat, 24 May 2025 03:16:51 -0300
Subject: [PATCH 1312/1697] Relative Date - FileAge
---
.../Views/PreviewPanel.xaml.cs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
index 801510eb7..28ceb5e96 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
@@ -73,7 +73,7 @@ public partial class PreviewPanel : UserControl, INotifyPropertyChanged
);
string result = formattedDate;
- if (Settings.ShowFileAgeInPreviewPanel) result = $"{GetRelativeDate(createdDate)} - {formattedDate}";
+ if (Settings.ShowFileAgeInPreviewPanel) result = $"{GetFileAge(createdDate)} - {formattedDate}";
CreatedAt = result;
}
@@ -85,7 +85,7 @@ public partial class PreviewPanel : UserControl, INotifyPropertyChanged
CultureInfo.CurrentCulture
);
string result = formattedDate;
- if (Settings.ShowFileAgeInPreviewPanel) result = $"{GetRelativeDate(lastModifiedDate)} - {formattedDate}";
+ if (Settings.ShowFileAgeInPreviewPanel) result = $"{GetFileAge(lastModifiedDate)} - {formattedDate}";
LastModifiedAt = result;
}
@@ -97,7 +97,7 @@ public partial class PreviewPanel : UserControl, INotifyPropertyChanged
PreviewImage = await Main.Context.API.LoadImageAsync(FilePath, true).ConfigureAwait(false);
}
- private string GetRelativeDate(DateTime fileDateTime)
+ private string GetFileAge(DateTime fileDateTime)
{
DateTime now = DateTime.Now;
TimeSpan difference = now - fileDateTime;
From 2ff0fc8a7d8de2306229f8439b530932974f4519 Mon Sep 17 00:00:00 2001
From: DB p
Date: Sat, 24 May 2025 15:28:51 +0900
Subject: [PATCH 1313/1697] Disable ShowFileAgeInPreviewPanel by default
---
Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
index 158cf0347..49ad2d358 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
@@ -67,7 +67,7 @@ namespace Flow.Launcher.Plugin.Explorer
public bool ShowModifiedDateInPreviewPanel { get; set; } = true;
- public bool ShowFileAgeInPreviewPanel { get; set; } = true;
+ public bool ShowFileAgeInPreviewPanel { get; set; } = false;
public string PreviewPanelDateFormat { get; set; } = "yyyy-MM-dd";
From 03d3c9292dcfc3814a890b9e0806e975f3abff59 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 24 May 2025 15:55:37 +0800
Subject: [PATCH 1314/1697] Fix blnak lie
---
Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml | 2 --
Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs | 1 -
2 files changed, 3 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
index aa86d96cf..ca994455a 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
@@ -126,8 +126,6 @@
Use '>' to search in this directory, '*' to search for file extensions or '>*' to combine both searches.
-
-
Failed to load Everything SDK
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
index 49ad2d358..4f83fc72e 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
@@ -27,7 +27,6 @@ namespace Flow.Launcher.Plugin.Explorer
public string ExcludedFileTypes { get; set; } = "";
-
public bool UseLocationAsWorkingDir { get; set; } = false;
public bool ShowInlinedWindowsContextMenu { get; set; } = false;
From 65e0a0220b07bf58ff6ffed2a796ea1094a66b5c Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 24 May 2025 15:56:02 +0800
Subject: [PATCH 1315/1697] Revert changes in pt-br.xaml
---
Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-br.xaml | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-br.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-br.xaml
index ca7d9b48e..2754a5a99 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-br.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-br.xaml
@@ -29,9 +29,8 @@
Everything Setting
Preview Panel
Tamanho
- Data de Criação
- Data de Modificação
- Idade do Arquivo
+ Date Created
+ Date Modified
Display File Info
Date and time format
Sort Option:
From 0f718e5d920bab13a285f42b4fb9ac83c759a9af Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 24 May 2025 15:59:24 +0800
Subject: [PATCH 1316/1697] Code quality
---
.../Views/PreviewPanel.xaml.cs | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
index 28ceb5e96..eabe1ad41 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
@@ -97,26 +97,27 @@ public partial class PreviewPanel : UserControl, INotifyPropertyChanged
PreviewImage = await Main.Context.API.LoadImageAsync(FilePath, true).ConfigureAwait(false);
}
- private string GetFileAge(DateTime fileDateTime)
+ private static string GetFileAge(DateTime fileDateTime)
{
- DateTime now = DateTime.Now;
- TimeSpan difference = now - fileDateTime;
+ var now = DateTime.Now;
+ var difference = now - fileDateTime;
if (difference.TotalDays < 1)
return "Today";
if (difference.TotalDays < 30)
return $"{(int)difference.TotalDays} days ago";
- int monthsDiff = (now.Year - fileDateTime.Year) * 12 + now.Month - fileDateTime.Month;
+ var monthsDiff = (now.Year - fileDateTime.Year) * 12 + now.Month - fileDateTime.Month;
if (monthsDiff < 12)
return monthsDiff == 1 ? "1 month ago" : $"{monthsDiff} months ago";
- int yearsDiff = now.Year - fileDateTime.Year;
+ var yearsDiff = now.Year - fileDateTime.Year;
if (now.Month < fileDateTime.Month || (now.Month == fileDateTime.Month && now.Day < fileDateTime.Day))
yearsDiff--;
return yearsDiff == 1 ? "1 year ago" : $"{yearsDiff} years ago";
}
+
public event PropertyChangedEventHandler? PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
From 62d7256db43d03eb56084fe82e21641ef8fa1ceb Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 24 May 2025 16:07:15 +0800
Subject: [PATCH 1317/1697] Support transaltion for preview information
---
.../Flow.Launcher.Plugin.Explorer/Languages/en.xaml | 8 ++++++++
.../Views/PreviewPanel.xaml.cs | 11 +++++++----
2 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
index ca994455a..eefd6f4eb 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
@@ -167,4 +167,12 @@
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').
+
+
+ Today
+ {0} days ago
+ 1 month ago
+ {0} months ago
+ 1 year ago
+ {0} years ago
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
index eabe1ad41..e1a957199 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
@@ -103,19 +103,22 @@ public partial class PreviewPanel : UserControl, INotifyPropertyChanged
var difference = now - fileDateTime;
if (difference.TotalDays < 1)
- return "Today";
+ return Main.Context.API.GetTranslation("Today");
if (difference.TotalDays < 30)
- return $"{(int)difference.TotalDays} days ago";
+ return string.Format(Main.Context.API.GetTranslation("DaysAgo"), (int)difference.TotalDays);
var monthsDiff = (now.Year - fileDateTime.Year) * 12 + now.Month - fileDateTime.Month;
+ if (monthsDiff == 1)
+ return Main.Context.API.GetTranslation("OneMonthAgo");
if (monthsDiff < 12)
- return monthsDiff == 1 ? "1 month ago" : $"{monthsDiff} months ago";
+ return string.Format(Main.Context.API.GetTranslation("MonthsAgo"), monthsDiff);
var yearsDiff = now.Year - fileDateTime.Year;
if (now.Month < fileDateTime.Month || (now.Month == fileDateTime.Month && now.Day < fileDateTime.Day))
yearsDiff--;
- return yearsDiff == 1 ? "1 year ago" : $"{yearsDiff} years ago";
+ return yearsDiff == 1 ? Main.Context.API.GetTranslation("OneYearAgo") :
+ string.Format(Main.Context.API.GetTranslation("YearsAgo"), yearsDiff);
}
public event PropertyChangedEventHandler? PropertyChanged;
From de7438791ce0374975444eb0adb7b646b908463f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 25 May 2025 09:14:19 +0800
Subject: [PATCH 1318/1697] Fix argument null exception when updating plugin
directories for errornous plugins
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index aae8dd764..300603c69 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -187,11 +187,19 @@ namespace Flow.Launcher.Core.Plugin
{
if (AllowedLanguage.IsDotNet(metadata.Language))
{
+ if (string.IsNullOrEmpty(metadata.AssemblyName))
+ {
+ continue; // Skip if AssemblyName is not set, which can happen for errornous plugins
+ }
metadata.PluginSettingsDirectoryPath = Path.Combine(DataLocation.PluginSettingsDirectory, metadata.AssemblyName);
metadata.PluginCacheDirectoryPath = Path.Combine(DataLocation.PluginCacheDirectory, metadata.AssemblyName);
}
else
{
+ if (string.IsNullOrEmpty(metadata.Name))
+ {
+ continue; // Skip if Name is not set, which can happen for errornous plugins
+ }
metadata.PluginSettingsDirectoryPath = Path.Combine(DataLocation.PluginSettingsDirectory, metadata.Name);
metadata.PluginCacheDirectoryPath = Path.Combine(DataLocation.PluginCacheDirectory, metadata.Name);
}
From 0d785d1c9ce819a0b0c7afe8f0110c947f727031 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 25 May 2025 09:17:31 +0800
Subject: [PATCH 1319/1697] Fix typos
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 300603c69..2689369f8 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -189,7 +189,7 @@ namespace Flow.Launcher.Core.Plugin
{
if (string.IsNullOrEmpty(metadata.AssemblyName))
{
- continue; // Skip if AssemblyName is not set, which can happen for errornous plugins
+ continue; // Skip if AssemblyName is not set, which can happen for erroneous plugins
}
metadata.PluginSettingsDirectoryPath = Path.Combine(DataLocation.PluginSettingsDirectory, metadata.AssemblyName);
metadata.PluginCacheDirectoryPath = Path.Combine(DataLocation.PluginCacheDirectory, metadata.AssemblyName);
@@ -198,7 +198,7 @@ namespace Flow.Launcher.Core.Plugin
{
if (string.IsNullOrEmpty(metadata.Name))
{
- continue; // Skip if Name is not set, which can happen for errornous plugins
+ continue; // Skip if Name is not set, which can happen for erroneous plugins
}
metadata.PluginSettingsDirectoryPath = Path.Combine(DataLocation.PluginSettingsDirectory, metadata.Name);
metadata.PluginCacheDirectoryPath = Path.Combine(DataLocation.PluginCacheDirectory, metadata.Name);
From 025895508326602066d1badf741182a91988ab26 Mon Sep 17 00:00:00 2001
From: Jack Ye <1160210343@qq.com>
Date: Sun, 25 May 2025 09:19:41 +0800
Subject: [PATCH 1320/1697] Log a warning when encountering an empty Name
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 1 +
1 file changed, 1 insertion(+)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 2689369f8..54b74da39 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -198,6 +198,7 @@ namespace Flow.Launcher.Core.Plugin
{
if (string.IsNullOrEmpty(metadata.Name))
{
+ Log.Warn($"Plugin with empty Name encountered. Skipping plugin initialization. Metadata: {metadata}");
continue; // Skip if Name is not set, which can happen for erroneous plugins
}
metadata.PluginSettingsDirectoryPath = Path.Combine(DataLocation.PluginSettingsDirectory, metadata.Name);
From 9e666f95ea6044b855f423c980f0db2090f6ff5f Mon Sep 17 00:00:00 2001
From: Jack Ye <1160210343@qq.com>
Date: Sun, 25 May 2025 09:19:54 +0800
Subject: [PATCH 1321/1697] Log a warning when encountering an empty
AssemblyName
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 1 +
1 file changed, 1 insertion(+)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 54b74da39..c4e505ad0 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -189,6 +189,7 @@ namespace Flow.Launcher.Core.Plugin
{
if (string.IsNullOrEmpty(metadata.AssemblyName))
{
+ Log.Warn($"Plugin skipped: AssemblyName is empty for plugin with metadata: {metadata.Name}", typeof(PluginManager));
continue; // Skip if AssemblyName is not set, which can happen for erroneous plugins
}
metadata.PluginSettingsDirectoryPath = Path.Combine(DataLocation.PluginSettingsDirectory, metadata.AssemblyName);
From 50780db9f54c1b2eef27859a9583fd75d85ff626 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 25 May 2025 09:20:57 +0800
Subject: [PATCH 1322/1697] Fix build issue
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index c4e505ad0..9b525f331 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -189,7 +189,7 @@ namespace Flow.Launcher.Core.Plugin
{
if (string.IsNullOrEmpty(metadata.AssemblyName))
{
- Log.Warn($"Plugin skipped: AssemblyName is empty for plugin with metadata: {metadata.Name}", typeof(PluginManager));
+ API.LogWarn(ClassName, $"AssemblyName is empty for plugin with metadata: {metadata.Name}");
continue; // Skip if AssemblyName is not set, which can happen for erroneous plugins
}
metadata.PluginSettingsDirectoryPath = Path.Combine(DataLocation.PluginSettingsDirectory, metadata.AssemblyName);
@@ -199,7 +199,7 @@ namespace Flow.Launcher.Core.Plugin
{
if (string.IsNullOrEmpty(metadata.Name))
{
- Log.Warn($"Plugin with empty Name encountered. Skipping plugin initialization. Metadata: {metadata}");
+ API.LogWarn(ClassName, $"Name is empty for plugin with metadata: {metadata.Name}");
continue; // Skip if Name is not set, which can happen for erroneous plugins
}
metadata.PluginSettingsDirectoryPath = Path.Combine(DataLocation.PluginSettingsDirectory, metadata.Name);
From 5bae2020313e836ed8c15699cb007f260dce67be Mon Sep 17 00:00:00 2001
From: 01Dri
Date: Sun, 25 May 2025 02:34:24 -0300
Subject: [PATCH 1323/1697] Columns - Path and Name
---
.../Views/ExplorerSettings.xaml | 22 +++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
index 4302e721a..3ef61573d 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
@@ -718,9 +718,27 @@
BorderThickness="1"
DragEnter="lbxAccessLinks_DragEnter"
Drop="LbxAccessLinks_OnDrop"
- ItemTemplate="{StaticResource ListViewTemplateAccessLinks}"
ItemsSource="{Binding Settings.QuickAccessLinks}"
- SelectedItem="{Binding SelectedQuickAccessLink}" />
+ SelectedItem="{Binding SelectedQuickAccessLink, Mode=TwoWay}">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Date: Sun, 25 May 2025 02:34:48 -0300
Subject: [PATCH 1324/1697] AccessLink Refactor
---
.../Search/QuickAccessLinks/AccessLink.cs | 21 +++++++++----------
1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/QuickAccessLinks/AccessLink.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/QuickAccessLinks/AccessLink.cs
index 1975211f9..8650b4c4c 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/QuickAccessLinks/AccessLink.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/QuickAccessLinks/AccessLink.cs
@@ -9,21 +9,20 @@ namespace Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks
public string Path { get; set; }
public ResultType Type { get; set; } = ResultType.Folder;
-
- [JsonIgnore]
- public string Name
+
+ public string Name { get; set; }
+
+ private string GetPathName()
{
- get
- {
- var path = Path.EndsWith(Constants.DirectorySeparator) ? Path[0..^1] : Path;
+ var path = Path.EndsWith(Constants.DirectorySeparator) ? Path[0..^1] : Path;
- if (path.EndsWith(':'))
- return path[0..^1] + " Drive";
+ if (path.EndsWith(':'))
+ return path[0..^1] + " Drive";
- return path.Split(new[] { System.IO.Path.DirectorySeparatorChar }, StringSplitOptions.None)
- .Last();
- }
+ return path.Split(new[] { System.IO.Path.DirectorySeparatorChar }, StringSplitOptions.None)
+ .Last();
}
+
}
}
From 179babe31371c27e55108c42e4e216ad595c6643 Mon Sep 17 00:00:00 2001
From: 01Dri
Date: Sun, 25 May 2025 02:35:09 -0300
Subject: [PATCH 1325/1697] New window to add/edit quick access link
---
.../Languages/en.xaml | 1 +
.../Views/QuickAccessLinkSettings.xaml | 136 ++++++++++++++++++
.../Views/QuickAccessLinkSettings.xaml.cs | 114 +++++++++++++++
3 files changed, 251 insertions(+)
create mode 100644 Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml
create mode 100644 Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
index eefd6f4eb..960373ef1 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
@@ -92,6 +92,7 @@
Permanently delete current file
Permanently delete current folder
Path:
+ Name:
Delete the selected
Run as different user
Run the selected using a different user account
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml
new file mode 100644
index 000000000..e6ad44e4e
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml
@@ -0,0 +1,136 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
new file mode 100644
index 000000000..9d2c54e2d
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
@@ -0,0 +1,114 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.IO;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Windows;
+using System.Windows.Forms;
+using Flow.Launcher.Plugin.Explorer.Search;
+using Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks;
+
+namespace Flow.Launcher.Plugin.Explorer.Views;
+
+public partial class QuickAccessLinkSettings : INotifyPropertyChanged
+{
+
+ private string _selectedPath;
+ public string SelectedPath
+ {
+ get => _selectedPath;
+ set
+ {
+ if (_selectedPath != value)
+ {
+ _selectedPath = value;
+ OnPropertyChanged();
+ SelectedName = GetPathName();
+ }
+ }
+ }
+
+
+ private string _selectedName;
+ public string SelectedName
+ {
+ get => _selectedName;
+ set
+ {
+ if (_selectedName != value)
+ {
+ _selectedName = value;
+ OnPropertyChanged();
+ }
+ }
+ }
+
+
+ public QuickAccessLinkSettings()
+ {
+ InitializeComponent();
+ }
+
+
+
+ private void BtnCancel_OnClick(object sender, RoutedEventArgs e)
+ {
+ DialogResult = false;
+ Close();
+ }
+
+ private void OnDoneButtonClick(object sender, RoutedEventArgs e)
+ {
+ var container = Settings.QuickAccessLinks;
+
+
+ // Lembrar de colocar uma logica pra evitar path e name vazios
+ var newAccessLink = new AccessLink
+ {
+ Name = SelectedName,
+ Path = SelectedPath
+ };
+ container.Add(newAccessLink);
+ DialogResult = false;
+ Close();
+ }
+
+ private void SelectPath_OnClick(object commandParameter, RoutedEventArgs e)
+ {
+ var folderBrowserDialog = new FolderBrowserDialog();
+
+ if (folderBrowserDialog.ShowDialog() != System.Windows.Forms.DialogResult.OK)
+ return;
+
+ SelectedPath = folderBrowserDialog.SelectedPath;
+ }
+
+ private string GetPathName()
+ {
+ if (string.IsNullOrEmpty(SelectedPath)) return "";
+ var path = SelectedPath.EndsWith(Constants.DirectorySeparator) ? SelectedPath[0..^1] : SelectedPath;
+
+ if (path.EndsWith(':'))
+ return path[0..^1] + " Drive";
+
+ return path.Split(new[] { Path.DirectorySeparatorChar }, StringSplitOptions.None)
+ .Last();
+ }
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ }
+
+ protected bool SetField(ref T field, T value, [CallerMemberName] string propertyName = null)
+ {
+ if (EqualityComparer.Default.Equals(field, value)) return false;
+ field = value;
+ OnPropertyChanged(propertyName);
+ return true;
+ }
+}
+
From 3777e2b6d86bfa2f689c942ee9bbf186dc50138d Mon Sep 17 00:00:00 2001
From: 01Dri
Date: Sun, 25 May 2025 02:36:55 -0300
Subject: [PATCH 1326/1697] Changing QuickAccessLinks property to static
This change is necessary for quick access settings window
---
Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
index 4f83fc72e..2380a1ec9 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
@@ -15,7 +15,7 @@ namespace Flow.Launcher.Plugin.Explorer
{
public int MaxResult { get; set; } = 100;
- public ObservableCollection QuickAccessLinks { get; set; } = new();
+ public static ObservableCollection QuickAccessLinks { get; set; } = new();
public ObservableCollection IndexSearchExcludedSubdirectoryPaths { get; set; } = new ObservableCollection();
From 61aca7409668890b1a55a14457ec02f0414d1209 Mon Sep 17 00:00:00 2001
From: 01Dri
Date: Sun, 25 May 2025 02:41:17 -0300
Subject: [PATCH 1327/1697] Separating add commands between QuickAccessLink and
IndexSearchExcludedPaths
---
.../ViewModels/SettingsViewModel.cs | 27 ++++++++++---------
.../Views/ExplorerSettings.xaml | 4 +--
2 files changed, 16 insertions(+), 15 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
index fb33dacab..508e20893 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
@@ -365,27 +365,28 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
}
[RelayCommand]
- private void AddLink(object commandParameter)
+ private void AddQuickAccessLink(object commandParameter)
{
- var container = commandParameter switch
- {
- "QuickAccessLink" => Settings.QuickAccessLinks,
- "IndexSearchExcludedPaths" => Settings.IndexSearchExcludedSubdirectoryPaths,
- _ => throw new ArgumentOutOfRangeException(nameof(commandParameter))
- };
-
- ArgumentNullException.ThrowIfNull(container);
-
+ var quickAccessLinkSettings = new QuickAccessLinkSettings();
+ quickAccessLinkSettings.ShowDialog();
+ }
+
+
+ [RelayCommand]
+ private void AddIndexSearchExcludePaths(object commandParameter)
+ {
+ var container = Settings.IndexSearchExcludedSubdirectoryPaths;
+
var folderBrowserDialog = new FolderBrowserDialog();
-
+
if (folderBrowserDialog.ShowDialog() != DialogResult.OK)
return;
-
+
var newAccessLink = new AccessLink
{
Path = folderBrowserDialog.SelectedPath
};
-
+
container.Add(newAccessLink);
}
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
index 3ef61573d..07f05b1c1 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
@@ -762,7 +762,7 @@
@@ -822,7 +822,7 @@
From 74167a91e39da13d45614228767ffa08f7ee9f4f Mon Sep 17 00:00:00 2001
From: 01Dri
Date: Sun, 25 May 2025 03:04:18 -0300
Subject: [PATCH 1328/1697] Strings translations and warning box
---
.../Languages/en.xaml | 4 ++++
.../Views/QuickAccessLinkSettings.xaml | 23 ++++++++++---------
.../Views/QuickAccessLinkSettings.xaml.cs | 12 +++++++++-
3 files changed, 27 insertions(+), 12 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
index 960373ef1..573fba4d9 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
@@ -5,6 +5,7 @@
Please make a selection first
+ Please select path folder
Please select a folder link
Are you sure you want to delete {0}?
Are you sure you want to permanently delete this file?
@@ -27,6 +28,9 @@
Add
General Setting
Customise Action Keywords
+ Customise Quick Access
+ Add
+
Quick Access Links
Everything Setting
Preview Panel
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml
index e6ad44e4e..ad2335c39 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml
@@ -61,7 +61,7 @@
Margin="0 0 0 0"
FontSize="20"
FontWeight="SemiBold"
- Text="{DynamicResource plugin_explorer_manageactionkeywords_header}"
+ Text="{DynamicResource plugin_explorer_manage_quick_access_links_header}"
TextAlignment="Left" />
@@ -71,11 +71,12 @@
HorizontalAlignment="Left"
VerticalAlignment="Center"
FontSize="14"
- Text="{DynamicResource plugin_explorer_actionkeyword_current}" />
+ Text="{DynamicResource plugin_explorer_name}" />
@@ -86,23 +87,23 @@
HorizontalAlignment="Left"
VerticalAlignment="Center"
FontSize="14"
- Text="Path:" />
+ Text="{DynamicResource plugin_explorer_path}" />
-
-
+ Text="{Binding SelectedPath, Mode=TwoWay}"
+ IsReadOnly="True" />
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
index 9d2c54e2d..6b881b244 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
@@ -33,7 +33,11 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
private string _selectedName;
public string SelectedName
{
- get => _selectedName;
+ get
+ {
+ if (string.IsNullOrEmpty(_selectedName)) return GetPathName();
+ return _selectedName;
+ }
set
{
if (_selectedName != value)
@@ -60,6 +64,12 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
private void OnDoneButtonClick(object sender, RoutedEventArgs e)
{
+ if (string.IsNullOrEmpty(SelectedName) && string.IsNullOrEmpty(SelectedPath))
+ {
+ var warning = Main.Context.API.GetTranslation("plugin_explorer_quick_access_link_no_folder_selected");
+ Main.Context.API.ShowMsgBox(warning);
+ return;
+ }
var container = Settings.QuickAccessLinks;
From 3b425413a22b925a1479db6ee2345aa69b5065c4 Mon Sep 17 00:00:00 2001
From: 01Dri
Date: Sun, 25 May 2025 04:31:08 -0300
Subject: [PATCH 1329/1697] Edit access link
---
.../Search/QuickAccessLinks/AccessLink.cs | 21 +-----
.../ViewModels/SettingsViewModel.cs | 36 +++++++----
.../Views/ExplorerSettings.xaml | 4 +-
.../Views/QuickAccessLinkSettings.xaml.cs | 64 +++++++++++++------
4 files changed, 74 insertions(+), 51 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/QuickAccessLinks/AccessLink.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/QuickAccessLinks/AccessLink.cs
index 8650b4c4c..ce086ac8c 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/QuickAccessLinks/AccessLink.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/QuickAccessLinks/AccessLink.cs
@@ -1,28 +1,13 @@
-using System;
-using System.Linq;
-using System.Text.Json.Serialization;
-
-namespace Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks
+namespace Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks
{
public class AccessLink
{
public string Path { get; set; }
public ResultType Type { get; set; } = ResultType.Folder;
-
+
public string Name { get; set; }
-
- private string GetPathName()
- {
- var path = Path.EndsWith(Constants.DirectorySeparator) ? Path[0..^1] : Path;
- if (path.EndsWith(':'))
- return path[0..^1] + " Drive";
-
- return path.Split(new[] { System.IO.Path.DirectorySeparatorChar }, StringSplitOptions.None)
- .Last();
- }
-
}
-
+
}
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
index 508e20893..eeb6b450e 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
@@ -328,33 +328,43 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
}
[RelayCommand]
- private void EditLink(object commandParameter)
+ private void EditQuickAccessLink(object commandParameter)
{
- var (selectedLink, collection) = commandParameter switch
+ if (SelectedQuickAccessLink is null)
{
- "QuickAccessLink" => (SelectedQuickAccessLink, Settings.QuickAccessLinks),
- "IndexSearchExcludedPaths" => (SelectedIndexSearchExcludedPath, Settings.IndexSearchExcludedSubdirectoryPaths),
- _ => throw new ArgumentOutOfRangeException(nameof(commandParameter))
- };
+ ShowUnselectedMessage();
+ return;
+ }
+
+ var quickAccessLinkSettings = new QuickAccessLinkSettings(SelectedQuickAccessLink);
+ quickAccessLinkSettings.ShowDialog();
+ }
- if (selectedLink is null)
+ [RelayCommand]
+ private void EditIndexSearchExcludePaths(object commandParameter)
+ {
+
+ var collection = Settings.IndexSearchExcludedSubdirectoryPaths;
+
+ if (SelectedIndexSearchExcludedPath is null)
{
ShowUnselectedMessage();
return;
}
- var path = PromptUserSelectPath(selectedLink.Type,
- selectedLink.Type == ResultType.Folder
- ? selectedLink.Path
- : Path.GetDirectoryName(selectedLink.Path));
+ var path = PromptUserSelectPath(SelectedIndexSearchExcludedPath.Type,
+ SelectedIndexSearchExcludedPath.Type == ResultType.Folder
+ ? SelectedIndexSearchExcludedPath.Path
+ : Path.GetDirectoryName(SelectedIndexSearchExcludedPath.Path));
if (path is null)
return;
- collection.Remove(selectedLink);
+ var selectedType = SelectedIndexSearchExcludedPath.Type;
+ collection.Remove(SelectedIndexSearchExcludedPath);
collection.Add(new AccessLink
{
- Path = path, Type = selectedLink.Type,
+ Path = path, Type = selectedType,
});
}
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
index 07f05b1c1..0a52487c3 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
@@ -756,7 +756,7 @@
_selectedPath;
@@ -29,8 +33,9 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
}
}
-
+
private string _selectedName;
+
public string SelectedName
{
get
@@ -48,20 +53,29 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
}
}
-
public QuickAccessLinkSettings()
{
InitializeComponent();
}
-
-
-
+
+ public QuickAccessLinkSettings(AccessLink selectedAccessLink)
+ {
+ IsEdit = true;
+ _selectedName = selectedAccessLink.Name;
+ _selectedPath = selectedAccessLink.Path;
+ SelectedAccessLink = selectedAccessLink;
+ InitializeComponent();
+ }
+
+
+
private void BtnCancel_OnClick(object sender, RoutedEventArgs e)
{
DialogResult = false;
Close();
}
+
private void OnDoneButtonClick(object sender, RoutedEventArgs e)
{
if (string.IsNullOrEmpty(SelectedName) && string.IsNullOrEmpty(SelectedPath))
@@ -70,15 +84,13 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
Main.Context.API.ShowMsgBox(warning);
return;
}
- var container = Settings.QuickAccessLinks;
-
-
- // Lembrar de colocar uma logica pra evitar path e name vazios
- var newAccessLink = new AccessLink
+ if (IsEdit)
{
- Name = SelectedName,
- Path = SelectedPath
- };
+ EditAccessLink();
+ return;
+ }
+ var container = Settings.QuickAccessLinks;
+ var newAccessLink = new AccessLink { Name = SelectedName, Path = SelectedPath };
container.Add(newAccessLink);
DialogResult = false;
Close();
@@ -87,13 +99,13 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
private void SelectPath_OnClick(object commandParameter, RoutedEventArgs e)
{
var folderBrowserDialog = new FolderBrowserDialog();
-
+
if (folderBrowserDialog.ShowDialog() != System.Windows.Forms.DialogResult.OK)
return;
SelectedPath = folderBrowserDialog.SelectedPath;
}
-
+
private string GetPathName()
{
if (string.IsNullOrEmpty(SelectedPath)) return "";
@@ -105,8 +117,24 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
return path.Split(new[] { Path.DirectorySeparatorChar }, StringSplitOptions.None)
.Last();
}
-
- public event PropertyChangedEventHandler PropertyChanged;
+
+ private void EditAccessLink()
+ {
+ if (SelectedAccessLink == null)throw new ArgumentException("Access Link object is null");
+
+ var obj = Settings.QuickAccessLinks.FirstOrDefault(x => x.GetHashCode() == SelectedAccessLink.GetHashCode());
+ int index = Settings.QuickAccessLinks.IndexOf(obj);
+ if (index >= 0)
+ {
+ SelectedAccessLink = new AccessLink { Name = SelectedName, Path = SelectedPath };
+ Settings.QuickAccessLinks[index] = SelectedAccessLink;
+ }
+ DialogResult = false;
+ IsEdit = false;
+ Close();
+ }
+
+public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
From 4b15add5244c9418fe0f444097c6691c62c04d83 Mon Sep 17 00:00:00 2001
From: 01Dri
Date: Sun, 25 May 2025 04:51:56 -0300
Subject: [PATCH 1330/1697] Code quality
---
.../ViewModels/SettingsViewModel.cs | 54 ++++++++++---------
.../Views/QuickAccessLinkSettings.xaml.cs | 13 +++--
2 files changed, 36 insertions(+), 31 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
index eeb6b450e..439f3f87f 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
@@ -327,18 +327,6 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
container.Add(link);
}
- [RelayCommand]
- private void EditQuickAccessLink(object commandParameter)
- {
- if (SelectedQuickAccessLink is null)
- {
- ShowUnselectedMessage();
- return;
- }
-
- var quickAccessLinkSettings = new QuickAccessLinkSettings(SelectedQuickAccessLink);
- quickAccessLinkSettings.ShowDialog();
- }
[RelayCommand]
private void EditIndexSearchExcludePaths(object commandParameter)
@@ -368,20 +356,6 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
});
}
- private void ShowUnselectedMessage()
- {
- var warning = Context.API.GetTranslation("plugin_explorer_make_selection_warning");
- Context.API.ShowMsgBox(warning);
- }
-
- [RelayCommand]
- private void AddQuickAccessLink(object commandParameter)
- {
- var quickAccessLinkSettings = new QuickAccessLinkSettings();
- quickAccessLinkSettings.ShowDialog();
- }
-
-
[RelayCommand]
private void AddIndexSearchExcludePaths(object commandParameter)
{
@@ -400,6 +374,28 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
container.Add(newAccessLink);
}
+ [RelayCommand]
+ private void EditQuickAccessLink(object commandParameter)
+ {
+ if (SelectedQuickAccessLink is null)
+ {
+ ShowUnselectedMessage();
+ return;
+ }
+
+ var quickAccessLinkSettings = new QuickAccessLinkSettings(SelectedQuickAccessLink);
+ quickAccessLinkSettings.ShowDialog();
+ }
+
+ [RelayCommand]
+ private void AddQuickAccessLink(object commandParameter)
+ {
+ var quickAccessLinkSettings = new QuickAccessLinkSettings();
+ quickAccessLinkSettings.ShowDialog();
+ }
+
+
+
[RelayCommand]
private void RemoveLink(object obj)
{
@@ -418,6 +414,12 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
}
Save();
}
+
+ private void ShowUnselectedMessage()
+ {
+ var warning = Context.API.GetTranslation("plugin_explorer_make_selection_warning");
+ Context.API.ShowMsgBox(warning);
+ }
#endregion
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
index 7bd67b54e..454935bd4 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
@@ -14,9 +14,7 @@ namespace Flow.Launcher.Plugin.Explorer.Views;
public partial class QuickAccessLinkSettings : INotifyPropertyChanged
{
-
- private bool IsEdit { get; set; }
- [CanBeNull] private AccessLink SelectedAccessLink { get; set; }
+
private string _selectedPath;
public string SelectedPath
@@ -28,7 +26,7 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
{
_selectedPath = value;
OnPropertyChanged();
- SelectedName = GetPathName();
+ if (string.IsNullOrEmpty(_selectedName)) SelectedName = GetPathName();
}
}
}
@@ -53,6 +51,8 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
}
}
+ private bool IsEdit { get; set; }
+ [CanBeNull] private AccessLink SelectedAccessLink { get; set; }
public QuickAccessLinkSettings()
{
InitializeComponent();
@@ -78,7 +78,7 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
private void OnDoneButtonClick(object sender, RoutedEventArgs e)
{
- if (string.IsNullOrEmpty(SelectedName) && string.IsNullOrEmpty(SelectedPath))
+ if (string.IsNullOrEmpty(SelectedName) || string.IsNullOrEmpty(SelectedPath))
{
var warning = Main.Context.API.GetTranslation("plugin_explorer_quick_access_link_no_folder_selected");
Main.Context.API.ShowMsgBox(warning);
@@ -122,6 +122,9 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
{
if (SelectedAccessLink == null)throw new ArgumentException("Access Link object is null");
+
+ // Talvez nao seja preciso buscar pelo hash code, mas sim pelo nome ou path
+ // Uma possivel validação, se pode nomes e paths iguais
var obj = Settings.QuickAccessLinks.FirstOrDefault(x => x.GetHashCode() == SelectedAccessLink.GetHashCode());
int index = Settings.QuickAccessLinks.IndexOf(obj);
if (index >= 0)
From 287f3f8a5f9b13fb3062944131ddaadc90b84df0 Mon Sep 17 00:00:00 2001
From: 01Dri
Date: Sun, 25 May 2025 14:12:15 -0300
Subject: [PATCH 1331/1697] Settings
---
Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs | 2 +-
.../ViewModels/SettingsViewModel.cs | 4 ++--
.../Views/QuickAccessLinkSettings.xaml.cs | 8 ++++++--
3 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
index 2380a1ec9..4f83fc72e 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
@@ -15,7 +15,7 @@ namespace Flow.Launcher.Plugin.Explorer
{
public int MaxResult { get; set; } = 100;
- public static ObservableCollection QuickAccessLinks { get; set; } = new();
+ public ObservableCollection QuickAccessLinks { get; set; } = new();
public ObservableCollection IndexSearchExcludedSubdirectoryPaths { get; set; } = new ObservableCollection();
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
index 439f3f87f..447e72736 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
@@ -383,14 +383,14 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
return;
}
- var quickAccessLinkSettings = new QuickAccessLinkSettings(SelectedQuickAccessLink);
+ var quickAccessLinkSettings = new QuickAccessLinkSettings(Settings,SelectedQuickAccessLink);
quickAccessLinkSettings.ShowDialog();
}
[RelayCommand]
private void AddQuickAccessLink(object commandParameter)
{
- var quickAccessLinkSettings = new QuickAccessLinkSettings();
+ var quickAccessLinkSettings = new QuickAccessLinkSettings(Settings);
quickAccessLinkSettings.ShowDialog();
}
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
index 454935bd4..3c9ba7ea5 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
@@ -53,17 +53,21 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
private bool IsEdit { get; set; }
[CanBeNull] private AccessLink SelectedAccessLink { get; set; }
- public QuickAccessLinkSettings()
+
+ private Settings Settings { get; }
+ public QuickAccessLinkSettings(Settings settings)
{
+ Settings = settings;
InitializeComponent();
}
- public QuickAccessLinkSettings(AccessLink selectedAccessLink)
+ public QuickAccessLinkSettings(Settings settings,AccessLink selectedAccessLink)
{
IsEdit = true;
_selectedName = selectedAccessLink.Name;
_selectedPath = selectedAccessLink.Path;
SelectedAccessLink = selectedAccessLink;
+ Settings = settings;
InitializeComponent();
}
From a6a544a48838ef52dc61410d7b222f01ff425d56 Mon Sep 17 00:00:00 2001
From: 01Dri
Date: Sun, 25 May 2025 14:26:47 -0300
Subject: [PATCH 1332/1697] Translations
---
Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml | 3 ++-
.../Views/QuickAccessLinkSettings.xaml.cs | 7 +++++++
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
index 573fba4d9..16bc9482f 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
@@ -5,7 +5,8 @@
Please make a selection first
- Please select path folder
+ Please select a folder path.
+ Please choose a different name or folder path.
Please select a folder link
Are you sure you want to delete {0}?
Are you sure you want to permanently delete this file?
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
index 3c9ba7ea5..e12898b5e 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
@@ -88,6 +88,13 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
Main.Context.API.ShowMsgBox(warning);
return;
}
+
+ if (Settings.QuickAccessLinks.Any(x => x.Path == SelectedPath && x.Name == SelectedName))
+ {
+ var warning = Main.Context.API.GetTranslation("plugin_explorer_quick_access_link_select_different_folder");
+ Main.Context.API.ShowMsgBox(warning);
+ return;
+ }
if (IsEdit)
{
EditAccessLink();
From fdeec1189627360c562b1662188f252ff7b4065c Mon Sep 17 00:00:00 2001
From: 01Dri
Date: Sun, 25 May 2025 14:45:44 -0300
Subject: [PATCH 1333/1697] FixLegacyQuickAccessLinkNames
---
.../Helper/FolderPathHelper.cs | 22 +++++++++++++++++
Plugins/Flow.Launcher.Plugin.Explorer/Main.cs | 15 +++++++++++-
.../Views/QuickAccessLinkSettings.xaml.cs | 24 ++++---------------
3 files changed, 40 insertions(+), 21 deletions(-)
create mode 100644 Plugins/Flow.Launcher.Plugin.Explorer/Helper/FolderPathHelper.cs
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Helper/FolderPathHelper.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Helper/FolderPathHelper.cs
new file mode 100644
index 000000000..74e23be3a
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Helper/FolderPathHelper.cs
@@ -0,0 +1,22 @@
+using System;
+using System.IO;
+using System.Linq;
+using Flow.Launcher.Plugin.Explorer.Search;
+
+namespace Flow.Launcher.Plugin.Explorer.Helper;
+
+public static class FolderPathHelper
+{
+ public static string GetPathName(this string selectedPath)
+ {
+ if (string.IsNullOrEmpty(selectedPath)) return "";
+ var path = selectedPath.EndsWith(Constants.DirectorySeparator) ? selectedPath[0..^1] : selectedPath;
+
+ if (path.EndsWith(':'))
+ return path[0..^1] + " Drive";
+
+ return path.Split(new[] { Path.DirectorySeparatorChar }, StringSplitOptions.None)
+ .Last();
+ }
+
+}
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Main.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Main.cs
index 1c5d074a0..cb2d29ec1 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Main.cs
@@ -6,6 +6,7 @@ using Flow.Launcher.Plugin.Explorer.Views;
using System;
using System.Collections.Generic;
using System.IO;
+using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Controls;
@@ -35,7 +36,8 @@ namespace Flow.Launcher.Plugin.Explorer
Context = context;
Settings = context.API.LoadSettingJsonStorage();
-
+ FixLegacyQuickAccessLinkNames();
+
viewModel = new SettingsViewModel(context, Settings);
contextMenu = new ContextMenu(Context, Settings, viewModel);
@@ -95,5 +97,16 @@ namespace Flow.Launcher.Plugin.Explorer
{
return Context.API.GetTranslation("plugin_explorer_plugin_description");
}
+
+ private void FixLegacyQuickAccessLinkNames()
+ {
+ foreach (var link in Settings.QuickAccessLinks)
+ {
+ if (string.IsNullOrWhiteSpace(link.Name))
+ {
+ link.Name = link.Path.GetPathName();
+ }
+ }
+ }
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
index e12898b5e..5eda62558 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
@@ -1,12 +1,11 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
-using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Forms;
-using Flow.Launcher.Plugin.Explorer.Search;
+using Flow.Launcher.Plugin.Explorer.Helper;
using Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks;
using JetBrains.Annotations;
@@ -26,7 +25,7 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
{
_selectedPath = value;
OnPropertyChanged();
- if (string.IsNullOrEmpty(_selectedName)) SelectedName = GetPathName();
+ if (string.IsNullOrEmpty(_selectedName)) SelectedName = _selectedPath.GetPathName();
}
}
}
@@ -38,7 +37,7 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
{
get
{
- if (string.IsNullOrEmpty(_selectedName)) return GetPathName();
+ if (string.IsNullOrEmpty(_selectedName)) return _selectedPath.GetPathName();
return _selectedName;
}
set
@@ -116,26 +115,11 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
SelectedPath = folderBrowserDialog.SelectedPath;
}
-
- private string GetPathName()
- {
- if (string.IsNullOrEmpty(SelectedPath)) return "";
- var path = SelectedPath.EndsWith(Constants.DirectorySeparator) ? SelectedPath[0..^1] : SelectedPath;
-
- if (path.EndsWith(':'))
- return path[0..^1] + " Drive";
-
- return path.Split(new[] { Path.DirectorySeparatorChar }, StringSplitOptions.None)
- .Last();
- }
-
+
private void EditAccessLink()
{
if (SelectedAccessLink == null)throw new ArgumentException("Access Link object is null");
-
- // Talvez nao seja preciso buscar pelo hash code, mas sim pelo nome ou path
- // Uma possivel validação, se pode nomes e paths iguais
var obj = Settings.QuickAccessLinks.FirstOrDefault(x => x.GetHashCode() == SelectedAccessLink.GetHashCode());
int index = Settings.QuickAccessLinks.IndexOf(obj);
if (index >= 0)
From 589e37a6465d481dcb2dc51f32419f8b3183c0b8 Mon Sep 17 00:00:00 2001
From: 01Dri
Date: Sun, 25 May 2025 15:49:25 -0300
Subject: [PATCH 1334/1697] Action QuickAccessLinks
---
Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs | 4 +++-
Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml | 2 --
.../Views/QuickAccessLinkSettings.xaml | 4 ++--
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs
index eabd118fb..195f7c91a 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs
@@ -75,7 +75,9 @@ namespace Flow.Launcher.Plugin.Explorer
{
Settings.QuickAccessLinks.Add(new AccessLink
{
- Path = record.FullPath, Type = record.Type
+ Name = record.FullPath.GetPathName(),
+ Path = record.FullPath,
+ Type = record.Type
});
Context.API.ShowMsg(Context.API.GetTranslation("plugin_explorer_addfilefoldersuccess"),
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
index 16bc9482f..ef55a4088 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
@@ -30,8 +30,6 @@
General Setting
Customise Action Keywords
Customise Quick Access
- Add
-
Quick Access Links
Everything Setting
Preview Panel
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml
index ad2335c39..e9ba53618 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml
@@ -4,7 +4,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Flow.Launcher.Plugin.Explorer.Views"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- Title="{DynamicResource plugin_explorer_manageactionkeywords_header}"
+ Title="{DynamicResource plugin_explorer_manage_quick_access_links_header}"
Width="Auto"
Height="255"
Background="{DynamicResource PopuBGColor}"
@@ -129,7 +129,7 @@
Margin="5 0 0 0"
Click="OnDoneButtonClick"
Style="{StaticResource AccentButtonStyle}">
-
+
From bc2648c216b4ee485c584bd81e1abb3ada9ba3cb Mon Sep 17 00:00:00 2001
From: 01Dri
Date: Sun, 25 May 2025 16:05:26 -0300
Subject: [PATCH 1335/1697] Code quality
---
.../ViewModels/SettingsViewModel.cs | 4 ++--
.../Views/QuickAccessLinkSettings.xaml.cs | 23 ++++++++++---------
2 files changed, 14 insertions(+), 13 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
index 447e72736..6237deabb 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
@@ -383,14 +383,14 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
return;
}
- var quickAccessLinkSettings = new QuickAccessLinkSettings(Settings,SelectedQuickAccessLink);
+ var quickAccessLinkSettings = new QuickAccessLinkSettings(Settings.QuickAccessLinks,SelectedQuickAccessLink);
quickAccessLinkSettings.ShowDialog();
}
[RelayCommand]
private void AddQuickAccessLink(object commandParameter)
{
- var quickAccessLinkSettings = new QuickAccessLinkSettings(Settings);
+ var quickAccessLinkSettings = new QuickAccessLinkSettings(Settings.QuickAccessLinks);
quickAccessLinkSettings.ShowDialog();
}
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
index 5eda62558..28cd68bad 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
@@ -53,20 +54,21 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
private bool IsEdit { get; set; }
[CanBeNull] private AccessLink SelectedAccessLink { get; set; }
- private Settings Settings { get; }
- public QuickAccessLinkSettings(Settings settings)
+ public ObservableCollection QuickAccessLinks { get; set; }
+
+ public QuickAccessLinkSettings(ObservableCollection quickAccessLinks)
{
- Settings = settings;
+ QuickAccessLinks = quickAccessLinks;
InitializeComponent();
}
- public QuickAccessLinkSettings(Settings settings,AccessLink selectedAccessLink)
+ public QuickAccessLinkSettings(ObservableCollection quickAccessLinks,AccessLink selectedAccessLink)
{
IsEdit = true;
_selectedName = selectedAccessLink.Name;
_selectedPath = selectedAccessLink.Path;
SelectedAccessLink = selectedAccessLink;
- Settings = settings;
+ QuickAccessLinks = quickAccessLinks;
InitializeComponent();
}
@@ -88,7 +90,7 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
return;
}
- if (Settings.QuickAccessLinks.Any(x => x.Path == SelectedPath && x.Name == SelectedName))
+ if (QuickAccessLinks.Any(x => x.Path == SelectedPath && x.Name == SelectedName))
{
var warning = Main.Context.API.GetTranslation("plugin_explorer_quick_access_link_select_different_folder");
Main.Context.API.ShowMsgBox(warning);
@@ -99,9 +101,8 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
EditAccessLink();
return;
}
- var container = Settings.QuickAccessLinks;
var newAccessLink = new AccessLink { Name = SelectedName, Path = SelectedPath };
- container.Add(newAccessLink);
+ QuickAccessLinks.Add(newAccessLink);
DialogResult = false;
Close();
}
@@ -120,12 +121,12 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
{
if (SelectedAccessLink == null)throw new ArgumentException("Access Link object is null");
- var obj = Settings.QuickAccessLinks.FirstOrDefault(x => x.GetHashCode() == SelectedAccessLink.GetHashCode());
- int index = Settings.QuickAccessLinks.IndexOf(obj);
+ var obj = QuickAccessLinks.FirstOrDefault(x => x.GetHashCode() == SelectedAccessLink.GetHashCode());
+ int index = QuickAccessLinks.IndexOf(obj);
if (index >= 0)
{
SelectedAccessLink = new AccessLink { Name = SelectedName, Path = SelectedPath };
- Settings.QuickAccessLinks[index] = SelectedAccessLink;
+ QuickAccessLinks[index] = SelectedAccessLink;
}
DialogResult = false;
IsEdit = false;
From cd62e7b5dc4695a83339d2a02c9682603d775479 Mon Sep 17 00:00:00 2001
From: 01Dri
Date: Sun, 25 May 2025 16:11:03 -0300
Subject: [PATCH 1336/1697] uP
---
.../Helper/{FolderPathHelper.cs => PathHelper.cs} | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
rename Plugins/Flow.Launcher.Plugin.Explorer/Helper/{FolderPathHelper.cs => PathHelper.cs} (94%)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Helper/FolderPathHelper.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Helper/PathHelper.cs
similarity index 94%
rename from Plugins/Flow.Launcher.Plugin.Explorer/Helper/FolderPathHelper.cs
rename to Plugins/Flow.Launcher.Plugin.Explorer/Helper/PathHelper.cs
index 74e23be3a..36b098d1e 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Helper/FolderPathHelper.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Helper/PathHelper.cs
@@ -5,7 +5,7 @@ using Flow.Launcher.Plugin.Explorer.Search;
namespace Flow.Launcher.Plugin.Explorer.Helper;
-public static class FolderPathHelper
+public static class PathHelper
{
public static string GetPathName(this string selectedPath)
{
From 29831d61bb2b496b88ecd8588c0518e506d7ea3e Mon Sep 17 00:00:00 2001
From: 01Dri
Date: Sun, 25 May 2025 16:48:20 -0300
Subject: [PATCH 1337/1697] AI Review Refactor suggestion
---
.../Languages/en.xaml | 2 +-
.../ViewModels/SettingsViewModel.cs | 10 ++++----
.../Views/QuickAccessLinkSettings.xaml.cs | 23 ++++++++++---------
3 files changed, 19 insertions(+), 16 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
index ef55a4088..cc6b58e42 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
@@ -6,7 +6,7 @@
Please make a selection first
Please select a folder path.
- Please choose a different name or folder path.
+ Please choose a different name or folder path.
Please select a folder link
Are you sure you want to delete {0}?
Are you sure you want to permanently delete this file?
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
index 6237deabb..d6effb4e2 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
@@ -9,6 +9,7 @@ using System.Linq;
using System.Windows;
using System.Windows.Forms;
using CommunityToolkit.Mvvm.Input;
+using Flow.Launcher.Plugin.Explorer.Helper;
using Flow.Launcher.Plugin.Explorer.Search;
using Flow.Launcher.Plugin.Explorer.Search.Everything;
using Flow.Launcher.Plugin.Explorer.Search.Everything.Exceptions;
@@ -352,7 +353,7 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
collection.Remove(SelectedIndexSearchExcludedPath);
collection.Add(new AccessLink
{
- Path = path, Type = selectedType,
+ Path = path, Type = selectedType, Name = path.GetPathName()
});
}
@@ -368,10 +369,12 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
var newAccessLink = new AccessLink
{
+ Name = folderBrowserDialog.SelectedPath.GetPathName(),
Path = folderBrowserDialog.SelectedPath
};
container.Add(newAccessLink);
+ Save();
}
[RelayCommand]
@@ -382,16 +385,15 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
ShowUnselectedMessage();
return;
}
-
var quickAccessLinkSettings = new QuickAccessLinkSettings(Settings.QuickAccessLinks,SelectedQuickAccessLink);
- quickAccessLinkSettings.ShowDialog();
+ if (quickAccessLinkSettings.ShowDialog() == true) Save();
}
[RelayCommand]
private void AddQuickAccessLink(object commandParameter)
{
var quickAccessLinkSettings = new QuickAccessLinkSettings(Settings.QuickAccessLinks);
- quickAccessLinkSettings.ShowDialog();
+ if (quickAccessLinkSettings.ShowDialog() == true) Save();
}
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
index 28cd68bad..388fc2c91 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
@@ -52,9 +52,9 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
}
private bool IsEdit { get; set; }
- [CanBeNull] private AccessLink SelectedAccessLink { get; set; }
+ [CanBeNull] private AccessLink SelectedAccessLink { get; }
- public ObservableCollection QuickAccessLinks { get; set; }
+ public ObservableCollection QuickAccessLinks { get; }
public QuickAccessLinkSettings(ObservableCollection quickAccessLinks)
{
@@ -89,10 +89,12 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
Main.Context.API.ShowMsgBox(warning);
return;
}
-
- if (QuickAccessLinks.Any(x => x.Path == SelectedPath && x.Name == SelectedName))
+
+ if (QuickAccessLinks.Any(x =>
+ x.Path.Equals(SelectedPath, StringComparison.OrdinalIgnoreCase) &&
+ x.Name.Equals(SelectedName, StringComparison.OrdinalIgnoreCase)))
{
- var warning = Main.Context.API.GetTranslation("plugin_explorer_quick_access_link_select_different_folder");
+ var warning = Main.Context.API.GetTranslation("plugin_explorer_quick_access_link_path_already_exists");
Main.Context.API.ShowMsgBox(warning);
return;
}
@@ -103,7 +105,7 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
}
var newAccessLink = new AccessLink { Name = SelectedName, Path = SelectedPath };
QuickAccessLinks.Add(newAccessLink);
- DialogResult = false;
+ DialogResult = true;
Close();
}
@@ -121,14 +123,13 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
{
if (SelectedAccessLink == null)throw new ArgumentException("Access Link object is null");
- var obj = QuickAccessLinks.FirstOrDefault(x => x.GetHashCode() == SelectedAccessLink.GetHashCode());
- int index = QuickAccessLinks.IndexOf(obj);
+ var index = QuickAccessLinks.IndexOf(SelectedAccessLink);
if (index >= 0)
{
- SelectedAccessLink = new AccessLink { Name = SelectedName, Path = SelectedPath };
- QuickAccessLinks[index] = SelectedAccessLink;
+ var updatedLink = new AccessLink { Name = SelectedName, Path = SelectedPath };
+ QuickAccessLinks[index] = updatedLink;
}
- DialogResult = false;
+ DialogResult = true;
IsEdit = false;
Close();
}
From 47878f3829a9cb10f87d5429d07fad097efec3dd Mon Sep 17 00:00:00 2001
From: DB p
Date: Tue, 27 May 2025 14:08:32 +0900
Subject: [PATCH 1338/1697] Fix file explorer invocation to ensure correct file
selection behavior
---
Flow.Launcher/PublicAPIInstance.cs | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 66e11f881..93567288c 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -338,7 +338,10 @@ namespace Flow.Launcher
// Windows File Manager
explorer.StartInfo = new ProcessStartInfo
{
- FileName = targetPath,
+ FileName = "explorer.exe",
+ Arguments = FileNameOrFilePath is null
+ ? DirectoryPath // only open the directory
+ : $"/select,\"{targetPath}\"", // open the directory and select the file
UseShellExecute = true
};
}
From 41c5b36fba5aa1a627c153db7fa9f7ffc525dd4b Mon Sep 17 00:00:00 2001
From: DB p
Date: Tue, 27 May 2025 15:20:41 +0900
Subject: [PATCH 1339/1697] Enhance OpenDirectory method to support folder
opening and file selection using SHOpenFolderAndSelectItems
---
Flow.Launcher/PublicAPIInstance.cs | 99 +++++++++++++++++++++++-------
1 file changed, 76 insertions(+), 23 deletions(-)
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 93567288c..58dbd3ff0 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -8,6 +8,7 @@ using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
@@ -320,47 +321,98 @@ namespace Flow.Launcher
((PluginJsonStorage)_pluginJsonStorages[type]).Save();
}
- public void OpenDirectory(string DirectoryPath, string FileNameOrFilePath = null)
+ [DllImport("shell32.dll", CharSet = CharSet.Unicode)]
+ private static extern int SHParseDisplayName(
+ [MarshalAs(UnmanagedType.LPWStr)] string name,
+ IntPtr bindingContext,
+ out IntPtr pidl,
+ uint sfgaoIn,
+ out uint psfgaoOut
+ );
+
+ [DllImport("shell32.dll")]
+ private static extern int SHOpenFolderAndSelectItems(
+ IntPtr pidlFolder,
+ uint cidl,
+ [MarshalAs(UnmanagedType.LPArray)] IntPtr[] apidl,
+ uint dwFlags
+ );
+
+ [DllImport("ole32.dll")]
+ private static extern void CoTaskMemFree(IntPtr pv);
+
+ private void OpenFolderAndSelectItem(string filePath)
+ {
+ IntPtr pidlFolder = IntPtr.Zero;
+ IntPtr pidlFile = IntPtr.Zero;
+ uint attr;
+
+ string folderPath = Path.GetDirectoryName(filePath);
+
+ try
+ {
+ SHParseDisplayName(folderPath, IntPtr.Zero, out pidlFolder, 0, out attr);
+ SHParseDisplayName(filePath, IntPtr.Zero, out pidlFile, 0, out attr);
+
+ if (pidlFolder != IntPtr.Zero && pidlFile != IntPtr.Zero)
+ {
+ SHOpenFolderAndSelectItems(pidlFolder, 1, new[] { pidlFile }, 0);
+ }
+ }
+ finally
+ {
+ if (pidlFile != IntPtr.Zero)
+ CoTaskMemFree(pidlFile);
+ if (pidlFolder != IntPtr.Zero)
+ CoTaskMemFree(pidlFolder);
+ }
+ }
+
+ public void OpenDirectory(string directoryPath, string fileNameOrFilePath = null)
{
try
{
- using var explorer = new Process();
+ string targetPath = fileNameOrFilePath is null
+ ? directoryPath
+ : Path.IsPathRooted(fileNameOrFilePath)
+ ? fileNameOrFilePath
+ : Path.Combine(directoryPath, fileNameOrFilePath);
+
var explorerInfo = _settings.CustomExplorer;
var explorerPath = explorerInfo.Path.Trim().ToLowerInvariant();
- var targetPath = FileNameOrFilePath is null
- ? DirectoryPath
- : Path.IsPathRooted(FileNameOrFilePath)
- ? FileNameOrFilePath
- : Path.Combine(DirectoryPath, FileNameOrFilePath);
if (Path.GetFileNameWithoutExtension(explorerPath) == "explorer")
{
- // Windows File Manager
- explorer.StartInfo = new ProcessStartInfo
+ if (fileNameOrFilePath is null)
{
- FileName = "explorer.exe",
- Arguments = FileNameOrFilePath is null
- ? DirectoryPath // only open the directory
- : $"/select,\"{targetPath}\"", // open the directory and select the file
- UseShellExecute = true
- };
+ // 폴더만 열기
+ Process.Start(new ProcessStartInfo
+ {
+ FileName = directoryPath,
+ UseShellExecute = true
+ })?.Dispose();
+ }
+ else
+ {
+ // SHOpenFolderAndSelectItems 방식
+ OpenFolderAndSelectItem(targetPath);
+ }
}
else
{
- // Custom File Manager
- explorer.StartInfo = new ProcessStartInfo
+ // 커스텀 파일 관리자
+ var shellProcess = new ProcessStartInfo
{
- FileName = explorerInfo.Path.Replace("%d", DirectoryPath),
+ FileName = explorerInfo.Path.Replace("%d", directoryPath),
UseShellExecute = true,
- Arguments = FileNameOrFilePath is null
- ? explorerInfo.DirectoryArgument.Replace("%d", DirectoryPath)
+ Arguments = fileNameOrFilePath is null
+ ? explorerInfo.DirectoryArgument.Replace("%d", directoryPath)
: explorerInfo.FileArgument
- .Replace("%d", DirectoryPath)
+ .Replace("%d", directoryPath)
.Replace("%f", targetPath)
};
+ Process.Start(shellProcess)?.Dispose();
}
-
- explorer.Start();
}
catch (Win32Exception ex) when (ex.NativeErrorCode == 2)
{
@@ -384,6 +436,7 @@ namespace Flow.Launcher
}
}
+
private void OpenUri(Uri uri, bool? inPrivate = null)
{
if (uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps)
From 086aeab6c05f4b2ab13e6d0a8239db7d83c588b1 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 27 May 2025 14:36:09 +0800
Subject: [PATCH 1340/1697] Use PInvoke to improve code quality
---
.../NativeMethods.txt | 4 +
Flow.Launcher.Infrastructure/Win32Helper.cs | 31 ++++++++
Flow.Launcher/PublicAPIInstance.cs | 76 ++++---------------
3 files changed, 50 insertions(+), 61 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/NativeMethods.txt b/Flow.Launcher.Infrastructure/NativeMethods.txt
index 0e50420b0..2591506c8 100644
--- a/Flow.Launcher.Infrastructure/NativeMethods.txt
+++ b/Flow.Launcher.Infrastructure/NativeMethods.txt
@@ -57,3 +57,7 @@ LOCALE_TRANSIENT_KEYBOARD1
LOCALE_TRANSIENT_KEYBOARD2
LOCALE_TRANSIENT_KEYBOARD3
LOCALE_TRANSIENT_KEYBOARD4
+
+SHParseDisplayName
+SHOpenFolderAndSelectItems
+CoTaskMemFree
diff --git a/Flow.Launcher.Infrastructure/Win32Helper.cs b/Flow.Launcher.Infrastructure/Win32Helper.cs
index 783ade14e..4952eec98 100644
--- a/Flow.Launcher.Infrastructure/Win32Helper.cs
+++ b/Flow.Launcher.Infrastructure/Win32Helper.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
+using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
@@ -17,6 +18,7 @@ using Windows.Win32;
using Windows.Win32.Foundation;
using Windows.Win32.Graphics.Dwm;
using Windows.Win32.UI.Input.KeyboardAndMouse;
+using Windows.Win32.UI.Shell.Common;
using Windows.Win32.UI.WindowsAndMessaging;
using Point = System.Windows.Point;
using SystemFonts = System.Windows.SystemFonts;
@@ -753,5 +755,34 @@ namespace Flow.Launcher.Infrastructure
}
#endregion
+
+ #region Explorer
+
+ public static unsafe void OpenFolderAndSelectFile(string filePath)
+ {
+ ITEMIDLIST* pidlFolder = null;
+ ITEMIDLIST* pidlFile = null;
+
+ var folderPath = Path.GetDirectoryName(filePath);
+
+ try
+ {
+ var hrFolder = PInvoke.SHParseDisplayName(folderPath, null, out pidlFolder, 0, null);
+ if (hrFolder.Failed) throw new COMException("Failed to parse folder path", hrFolder);
+
+ var hrFile = PInvoke.SHParseDisplayName(filePath, null, out pidlFile, 0, null);
+ if (hrFile.Failed) throw new COMException("Failed to parse file path", hrFile);
+
+ var hrSelect = PInvoke.SHOpenFolderAndSelectItems(pidlFolder, 1, &pidlFile, 0);
+ if (hrSelect.Failed) throw new COMException("Failed to open folder and select item", hrSelect);
+ }
+ finally
+ {
+ if (pidlFile != null) PInvoke.CoTaskMemFree(pidlFile);
+ if (pidlFolder != null) PInvoke.CoTaskMemFree(pidlFolder);
+ }
+ }
+
+ #endregion
}
}
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 58dbd3ff0..c06c56039 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -8,11 +8,9 @@ using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
-using System.Windows.Input;
using System.Windows.Media;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Core;
@@ -320,88 +318,44 @@ namespace Flow.Launcher
((PluginJsonStorage)_pluginJsonStorages[type]).Save();
}
-
- [DllImport("shell32.dll", CharSet = CharSet.Unicode)]
- private static extern int SHParseDisplayName(
- [MarshalAs(UnmanagedType.LPWStr)] string name,
- IntPtr bindingContext,
- out IntPtr pidl,
- uint sfgaoIn,
- out uint psfgaoOut
- );
-
- [DllImport("shell32.dll")]
- private static extern int SHOpenFolderAndSelectItems(
- IntPtr pidlFolder,
- uint cidl,
- [MarshalAs(UnmanagedType.LPArray)] IntPtr[] apidl,
- uint dwFlags
- );
-
- [DllImport("ole32.dll")]
- private static extern void CoTaskMemFree(IntPtr pv);
-
- private void OpenFolderAndSelectItem(string filePath)
- {
- IntPtr pidlFolder = IntPtr.Zero;
- IntPtr pidlFile = IntPtr.Zero;
- uint attr;
-
- string folderPath = Path.GetDirectoryName(filePath);
-
- try
- {
- SHParseDisplayName(folderPath, IntPtr.Zero, out pidlFolder, 0, out attr);
- SHParseDisplayName(filePath, IntPtr.Zero, out pidlFile, 0, out attr);
-
- if (pidlFolder != IntPtr.Zero && pidlFile != IntPtr.Zero)
- {
- SHOpenFolderAndSelectItems(pidlFolder, 1, new[] { pidlFile }, 0);
- }
- }
- finally
- {
- if (pidlFile != IntPtr.Zero)
- CoTaskMemFree(pidlFile);
- if (pidlFolder != IntPtr.Zero)
- CoTaskMemFree(pidlFolder);
- }
- }
public void OpenDirectory(string directoryPath, string fileNameOrFilePath = null)
{
try
{
- string targetPath = fileNameOrFilePath is null
+ var explorerInfo = _settings.CustomExplorer;
+ var explorerPath = explorerInfo.Path.Trim().ToLowerInvariant();
+ var targetPath = fileNameOrFilePath is null
? directoryPath
: Path.IsPathRooted(fileNameOrFilePath)
? fileNameOrFilePath
: Path.Combine(directoryPath, fileNameOrFilePath);
- var explorerInfo = _settings.CustomExplorer;
- var explorerPath = explorerInfo.Path.Trim().ToLowerInvariant();
-
if (Path.GetFileNameWithoutExtension(explorerPath) == "explorer")
{
+ // Windows File Manager
if (fileNameOrFilePath is null)
{
- // 폴더만 열기
- Process.Start(new ProcessStartInfo
+ // Only Open the directory
+ using var explorer = new Process();
+ explorer.StartInfo = new ProcessStartInfo
{
FileName = directoryPath,
UseShellExecute = true
- })?.Dispose();
+ };
+ explorer.Start();
}
else
{
- // SHOpenFolderAndSelectItems 방식
- OpenFolderAndSelectItem(targetPath);
+ // Open the directory and select the file
+ Win32Helper.OpenFolderAndSelectFile(targetPath);
}
}
else
{
- // 커스텀 파일 관리자
- var shellProcess = new ProcessStartInfo
+ // Custom File Manager
+ using var explorer = new Process();
+ explorer.StartInfo = new ProcessStartInfo
{
FileName = explorerInfo.Path.Replace("%d", directoryPath),
UseShellExecute = true,
@@ -411,7 +365,7 @@ namespace Flow.Launcher
.Replace("%d", directoryPath)
.Replace("%f", targetPath)
};
- Process.Start(shellProcess)?.Dispose();
+ explorer.Start();
}
}
catch (Win32Exception ex) when (ex.NativeErrorCode == 2)
From eb69ce919e65b7b35fe48722f7a7ba8e9aa49096 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 27 May 2025 14:36:24 +0800
Subject: [PATCH 1341/1697] Add url comments
---
Flow.Launcher.Infrastructure/Win32Helper.cs | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Flow.Launcher.Infrastructure/Win32Helper.cs b/Flow.Launcher.Infrastructure/Win32Helper.cs
index 4952eec98..96d8e925b 100644
--- a/Flow.Launcher.Infrastructure/Win32Helper.cs
+++ b/Flow.Launcher.Infrastructure/Win32Helper.cs
@@ -758,6 +758,8 @@ namespace Flow.Launcher.Infrastructure
#region Explorer
+ // https://learn.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shopenfolderandselectitems
+
public static unsafe void OpenFolderAndSelectFile(string filePath)
{
ITEMIDLIST* pidlFolder = null;
From 489699ca89a86047509a1dc8a8dd180d986d22b1 Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Tue, 27 May 2025 10:46:07 +0000
Subject: [PATCH 1342/1697] add update PR script
---
.github/update_release_pr.py | 103 +++++++++++++++++++++++++++++++++++
1 file changed, 103 insertions(+)
create mode 100644 .github/update_release_pr.py
diff --git a/.github/update_release_pr.py b/.github/update_release_pr.py
new file mode 100644
index 000000000..a9d11651b
--- /dev/null
+++ b/.github/update_release_pr.py
@@ -0,0 +1,103 @@
+import os
+import requests
+
+def get_github_prs(token, owner, repo, milestone, label, state):
+ """
+ Fetches pull requests from a GitHub repository that match a given milestone and label.
+
+ Args:
+ token (str): GitHub token.
+ owner (str): The owner of the repository.
+ repo (str): The name of the repository.
+ milestone (str): The milestone title.
+ label (str): The label name.
+ state (str): State of PR, e.g. open
+
+ Returns:
+ list: A list of dictionaries, where each dictionary represents a pull request.
+ Returns an empty list if no PRs are found or an error occurs.
+ """
+ headers = {
+ "Authorization": f"token {token}",
+ "Accept": "application/vnd.github.v3+json",
+ }
+
+ milestone_id = None
+ milestone_url = f"https://api.github.com/repos/{owner}/{repo}/milestones"
+ params = {"state": state}
+
+ try:
+ response = requests.get(milestone_url, headers=headers, params=params)
+ response.raise_for_status()
+ milestones = response.json()
+ for ms in milestones:
+ if ms["title"] == milestone:
+ milestone_id = ms["number"]
+ break
+
+ if not milestone_id:
+ print(f"Milestone '{milestone}' not found in repository '{owner}/{repo}'.")
+ return []
+
+ except requests.exceptions.RequestException as e:
+ print(f"Error fetching milestones: {e}")
+ return []
+
+ prs_url = f"https://api.github.com/repos/{owner}/{repo}/pulls"
+ params = {
+ "state": state,
+ "milestone": milestone_id,
+ "labels": label,
+ }
+
+ all_prs = []
+ page = 1
+ while True:
+ try:
+ params["page"] = page
+ response = requests.get(prs_url, headers=headers, params=params)
+ response.raise_for_status() # Raise an exception for HTTP errors
+ prs = response.json()
+
+ if not prs:
+ break # No more PRs to fetch
+
+ all_prs.extend(prs)
+ page += 1
+
+ except requests.exceptions.RequestException as e:
+ print(f"Error fetching pull requests: {e}")
+ break
+
+ return all_prs
+
+if __name__ == "__main__":
+ github_token = os.environ.get("GITHUB_TOKEN")
+
+ if not github_token:
+ print("Error: GITHUB_TOKEN environment variable not set.")
+ exit(1)
+
+ repository_owner = "flow-launcher"
+ repository_name = "flow.launcher"
+ target_milestone = "1.20.0"
+ target_label = "enhancement"
+ state = "closed"
+
+ print(f"Fetching PRs for {repository_owner}/{repository_name} with milestone '{target_milestone}' and label '{target_label}'...")
+
+ pull_requests = get_github_prs(
+ github_token,
+ repository_owner,
+ repository_name,
+ target_milestone,
+ target_label,
+ state
+ )
+
+ if pull_requests:
+ print(f"\nFound {len(pull_requests)} pull requests:")
+ for pr in pull_requests:
+ print(f"- {pr['state']} #{pr['number']}: {pr['title']} (URL: {pr['html_url']})")
+ else:
+ print("No matching pull requests found.")
From f79a2d24674d7f6f208a6c09c8a60ba98618ea84 Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Tue, 27 May 2025 11:36:38 +0000
Subject: [PATCH 1343/1697] change to issues endpoint
---
.github/update_release_pr.py | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/.github/update_release_pr.py b/.github/update_release_pr.py
index a9d11651b..b51620d73 100644
--- a/.github/update_release_pr.py
+++ b/.github/update_release_pr.py
@@ -24,7 +24,7 @@ def get_github_prs(token, owner, repo, milestone, label, state):
milestone_id = None
milestone_url = f"https://api.github.com/repos/{owner}/{repo}/milestones"
- params = {"state": state}
+ params = {"state": open}
try:
response = requests.get(milestone_url, headers=headers, params=params)
@@ -37,17 +37,19 @@ def get_github_prs(token, owner, repo, milestone, label, state):
if not milestone_id:
print(f"Milestone '{milestone}' not found in repository '{owner}/{repo}'.")
- return []
+ exit(1)
except requests.exceptions.RequestException as e:
print(f"Error fetching milestones: {e}")
- return []
+ exit(1)
- prs_url = f"https://api.github.com/repos/{owner}/{repo}/pulls"
+ # This endpoint allows filtering by milestone and label. A PR in GH's perspective is a type of issue.
+ prs_url = f"https://api.github.com/repos/{owner}/{repo}/issues"
params = {
"state": state,
"milestone": milestone_id,
"labels": label,
+ "per_page": 100,
}
all_prs = []
@@ -61,18 +63,19 @@ def get_github_prs(token, owner, repo, milestone, label, state):
if not prs:
break # No more PRs to fetch
-
- all_prs.extend(prs)
+
+ # Check for pr key since we are using issues endpoint instead.
+ all_prs.extend([item for item in prs if "pull_request" in item])
page += 1
except requests.exceptions.RequestException as e:
print(f"Error fetching pull requests: {e}")
- break
+ exit(1)
return all_prs
if __name__ == "__main__":
- github_token = os.environ.get("GITHUB_TOKEN")
+ github_token = os.environ.get("GITHUB_TOKEN")
if not github_token:
print("Error: GITHUB_TOKEN environment variable not set.")
From 55b69c601a12899f054cedab4956a2cb0dcf95e5 Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Wed, 28 May 2025 11:20:39 +0000
Subject: [PATCH 1344/1697] get milestone dynamically
---
.github/update_release_pr.py | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/.github/update_release_pr.py b/.github/update_release_pr.py
index b51620d73..c00683439 100644
--- a/.github/update_release_pr.py
+++ b/.github/update_release_pr.py
@@ -1,7 +1,7 @@
import os
import requests
-def get_github_prs(token, owner, repo, milestone, label, state):
+def get_github_prs(token, owner, repo, label, state):
"""
Fetches pull requests from a GitHub repository that match a given milestone and label.
@@ -9,7 +9,6 @@ def get_github_prs(token, owner, repo, milestone, label, state):
token (str): GitHub token.
owner (str): The owner of the repository.
repo (str): The name of the repository.
- milestone (str): The milestone title.
label (str): The label name.
state (str): State of PR, e.g. open
@@ -30,13 +29,19 @@ def get_github_prs(token, owner, repo, milestone, label, state):
response = requests.get(milestone_url, headers=headers, params=params)
response.raise_for_status()
milestones = response.json()
+
+ if len(milestones) > 2:
+ print("More than two milestones found, unable to determine the milestone required.")
+
+ # milestones.pop()
for ms in milestones:
- if ms["title"] == milestone:
+ if ms["title"] != "Future":
milestone_id = ms["number"]
+ print(f"Gathering PRs with milestone {ms['title']}..." )
break
if not milestone_id:
- print(f"Milestone '{milestone}' not found in repository '{owner}/{repo}'.")
+ print(f"No suitable milestone found in repository '{owner}/{repo}'.")
exit(1)
except requests.exceptions.RequestException as e:
@@ -83,17 +88,15 @@ if __name__ == "__main__":
repository_owner = "flow-launcher"
repository_name = "flow.launcher"
- target_milestone = "1.20.0"
target_label = "enhancement"
state = "closed"
- print(f"Fetching PRs for {repository_owner}/{repository_name} with milestone '{target_milestone}' and label '{target_label}'...")
+ print(f"Fetching PRs for {repository_owner}/{repository_name} with label '{target_label}'...")
pull_requests = get_github_prs(
github_token,
repository_owner,
repository_name,
- target_milestone,
target_label,
state
)
From 0b616d8721d432fe940c2683c2edfb9695641bf3 Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Wed, 28 May 2025 12:03:13 +0000
Subject: [PATCH 1345/1697] add pr update
---
.github/update_release_pr.py | 84 +++++++++++++++++++++++++++++++++---
1 file changed, 77 insertions(+), 7 deletions(-)
diff --git a/.github/update_release_pr.py b/.github/update_release_pr.py
index c00683439..b03b0c425 100644
--- a/.github/update_release_pr.py
+++ b/.github/update_release_pr.py
@@ -79,6 +79,53 @@ def get_github_prs(token, owner, repo, label, state):
return all_prs
+def update_pull_request_description(token, owner, repo, pr_number, new_description):
+ """
+ Updates the description (body) of a GitHub Pull Request.
+
+ Args:
+ token (str): Token.
+ owner (str): The owner of the repository.
+ repo (str): The name of the repository.
+ pr_number (int): The number of the pull request to update.
+ new_description (str): The new content for the PR's description.
+
+ Returns:
+ dict or None: The updated PR object (as a dictionary) if successful,
+ None otherwise.
+ """
+ headers = {
+ "Authorization": f"token {token}",
+ "Accept": "application/vnd.github.v3+json",
+ "Content-Type": "application/json"
+ }
+
+ url = f"https://api.github.com/repos/{owner}/{repo}/pulls/{pr_number}"
+
+ payload = {
+ "body": new_description
+ }
+
+ print(f"Attempting to update PR #{pr_number} in {owner}/{repo}...")
+ print(f"URL: {url}")
+ # print(f"Payload: {payload}") # Uncomment for detailed payload debug
+
+ try:
+ response = requests.patch(url, headers=headers, json=payload)
+ response.raise_for_status()
+
+ updated_pr_data = response.json()
+ print(f"Successfully updated PR #{pr_number}.")
+ return updated_pr_data
+
+ except requests.exceptions.RequestException as e:
+ print(f"Error updating pull request #{pr_number}: {e}")
+ if response is not None:
+ print(f"Response status code: {response.status_code}")
+ print(f"Response text: {response.text}")
+ return None
+
+
if __name__ == "__main__":
github_token = os.environ.get("GITHUB_TOKEN")
@@ -92,7 +139,7 @@ if __name__ == "__main__":
state = "closed"
print(f"Fetching PRs for {repository_owner}/{repository_name} with label '{target_label}'...")
-
+
pull_requests = get_github_prs(
github_token,
repository_owner,
@@ -101,9 +148,32 @@ if __name__ == "__main__":
state
)
- if pull_requests:
- print(f"\nFound {len(pull_requests)} pull requests:")
- for pr in pull_requests:
- print(f"- {pr['state']} #{pr['number']}: {pr['title']} (URL: {pr['html_url']})")
- else:
- print("No matching pull requests found.")
+ if not pull_requests:
+ print("No matching pull requests found")
+ exit(1)
+
+ print(f"\nFound {len(pull_requests)} pull requests:")
+
+ description_content = ""
+ for pr in pull_requests:
+ description_content+= f"- {pr['title']} #{pr['number']}\n"
+
+ returned_pr = pull_requests = get_github_prs(
+ github_token,
+ repository_owner,
+ repository_name,
+ "release",
+ "open"
+ )
+
+ if len(returned_pr) != 1:
+ print(f"Unable to find the exact release PR. Returned result: {returned_pr}")
+ exit(1)
+
+ release_pr = returned_pr[0]
+
+ print(f"Found release PR: {release_pr['title']}")
+
+ update_pull_request_description(github_token, repository_owner, repository_name, release_pr["number"], description_content)
+
+ print(description_content)
\ No newline at end of file
From 4a50eec281e6013301efd5b56eb5c601d3921565 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 30 May 2025 10:59:22 +0800
Subject: [PATCH 1346/1697] Remove TranslationConverter & project reference in
Explorer plugin
---
.../Resource/TranslationConverter.cs | 25 -------------------
.../UserSettings/CustomShortcutModel.cs | 8 ++++++
.../Resources/SettingWindowStyle.xaml | 1 -
.../Views/SettingsPaneHotkey.xaml | 2 +-
.../Flow.Launcher.Plugin.Explorer.csproj | 3 +--
.../ViewModels/ActionKeywordModel.cs | 2 ++
.../Views/ExplorerSettings.xaml | 6 ++---
7 files changed, 14 insertions(+), 33 deletions(-)
delete mode 100644 Flow.Launcher.Core/Resource/TranslationConverter.cs
diff --git a/Flow.Launcher.Core/Resource/TranslationConverter.cs b/Flow.Launcher.Core/Resource/TranslationConverter.cs
deleted file mode 100644
index eb0032758..000000000
--- a/Flow.Launcher.Core/Resource/TranslationConverter.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-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 API.GetTranslation(key);
- }
-
- public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) =>
- throw new InvalidOperationException();
- }
-}
diff --git a/Flow.Launcher.Infrastructure/UserSettings/CustomShortcutModel.cs b/Flow.Launcher.Infrastructure/UserSettings/CustomShortcutModel.cs
index 2d15b54c5..2603d4675 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/CustomShortcutModel.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/CustomShortcutModel.cs
@@ -1,6 +1,8 @@
using System;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
+using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.Plugin;
namespace Flow.Launcher.Infrastructure.UserSettings
{
@@ -53,6 +55,12 @@ namespace Flow.Launcher.Infrastructure.UserSettings
{
public string Description { get; set; }
+ public string LocalizedDescription => API.GetTranslation(Description);
+
+ // 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 BaseBuiltinShortcutModel(string key, string description)
{
Key = key;
diff --git a/Flow.Launcher/Resources/SettingWindowStyle.xaml b/Flow.Launcher/Resources/SettingWindowStyle.xaml
index fc9246aa3..3ebd22c74 100644
--- a/Flow.Launcher/Resources/SettingWindowStyle.xaml
+++ b/Flow.Launcher/Resources/SettingWindowStyle.xaml
@@ -6,7 +6,6 @@
-
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/SettingPages/Views/SettingsPaneHotkey.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml
index b1d72ede5..861e9d294 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml
@@ -424,7 +424,7 @@
-
+
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 98164f489..93691814a 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 @@
+
@@ -53,8 +54,6 @@
-
-
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/ActionKeywordModel.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/ActionKeywordModel.cs
index d4cd1348e..745032d2c 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/ActionKeywordModel.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/ActionKeywordModel.cs
@@ -24,6 +24,8 @@ namespace Flow.Launcher.Plugin.Explorer.Views
public string Description { get; private init; }
+ public string LocalizedDescription => Main.Context.API.GetTranslation(Description);
+
internal Settings.ActionKeyword KeywordProperty { get; }
private void OnPropertyChanged([CallerMemberName] string propertyName = "")
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
index 4302e721a..c034ac0e1 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
@@ -3,7 +3,6 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:converters="clr-namespace:Flow.Launcher.Plugin.Explorer.Views.Converters"
- xmlns:core="clr-namespace:Flow.Launcher.Core.Resource;assembly=Flow.Launcher.Core"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:qa="clr-namespace:Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks"
@@ -109,7 +108,7 @@
+ Text="{Binding LocalizedDescription, Mode=OneTime}">
+
From b1557dd4affb3d37949a515ea6e6c1585a13e501 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 4 Jun 2025 17:32:30 +0800
Subject: [PATCH 1398/1697] Add try-catch for preview panel operation
---
.../Views/PreviewPanel.xaml.cs | 119 ++++++++++++------
1 file changed, 81 insertions(+), 38 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
index 13339fa45..f4d7f8436 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
@@ -16,6 +16,8 @@ namespace Flow.Launcher.Plugin.Explorer.Views;
public partial class PreviewPanel : UserControl, INotifyPropertyChanged
{
+ private static readonly string ClassName = nameof(PreviewPanel);
+
private string FilePath { get; }
public string FileSize { get; } = "";
public string CreatedAt { get; } = "";
@@ -87,78 +89,119 @@ public partial class PreviewPanel : UserControl, INotifyPropertyChanged
public static string GetFileSize(string filePath)
{
- var fileInfo = new FileInfo(filePath);
- return ResultManager.ToReadableSize(fileInfo.Length, 2);
+ try
+ {
+ var fileInfo = new FileInfo(filePath);
+ return ResultManager.ToReadableSize(fileInfo.Length, 2);
+ }
+ catch (Exception e)
+ {
+ Main.Context.API.LogException(ClassName, $"Failed to get file size for {filePath}", e);
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
}
public static string GetFileCreatedAt(string filePath, string previewPanelDateFormat, string previewPanelTimeFormat, bool showFileAgeInPreviewPanel)
{
- var createdDate = File.GetCreationTime(filePath);
- var formattedDate = createdDate.ToString(
- $"{previewPanelDateFormat} {previewPanelTimeFormat}",
- CultureInfo.CurrentCulture
- );
+ try
+ {
+ var createdDate = File.GetCreationTime(filePath);
+ var formattedDate = createdDate.ToString(
+ $"{previewPanelDateFormat} {previewPanelTimeFormat}",
+ CultureInfo.CurrentCulture
+ );
- var result = formattedDate;
- if (showFileAgeInPreviewPanel) result = $"{GetFileAge(createdDate)} - {formattedDate}";
- return result;
+ var result = formattedDate;
+ if (showFileAgeInPreviewPanel) result = $"{GetFileAge(createdDate)} - {formattedDate}";
+ return result;
+ }
+ catch (Exception e)
+ {
+ Main.Context.API.LogException(ClassName, $"Failed to get file created date for {filePath}", e);
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
}
public static string GetFileLastModifiedAt(string filePath, string previewPanelDateFormat, string previewPanelTimeFormat, bool showFileAgeInPreviewPanel)
{
- var lastModifiedDate = File.GetLastWriteTime(filePath);
- var formattedDate = lastModifiedDate.ToString(
- $"{previewPanelDateFormat} {previewPanelTimeFormat}",
- CultureInfo.CurrentCulture
- );
+ try
+ {
+ var lastModifiedDate = File.GetLastWriteTime(filePath);
+ var formattedDate = lastModifiedDate.ToString(
+ $"{previewPanelDateFormat} {previewPanelTimeFormat}",
+ CultureInfo.CurrentCulture
+ );
- var result = formattedDate;
- if (showFileAgeInPreviewPanel) result = $"{GetFileAge(lastModifiedDate)} - {formattedDate}";
- return result;
+ var result = formattedDate;
+ if (showFileAgeInPreviewPanel) result = $"{GetFileAge(lastModifiedDate)} - {formattedDate}";
+ return result;
+ }
+ catch (Exception e)
+ {
+ Main.Context.API.LogException(ClassName, $"Failed to get file modified date for {filePath}", e);
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
}
public static string GetFolderSize(string folderPath)
{
- var directoryInfo = new DirectoryInfo(folderPath);
- long size = 0;
try
{
+ var directoryInfo = new DirectoryInfo(folderPath);
+ long size = 0;
foreach (var file in directoryInfo.GetFiles("*", SearchOption.AllDirectories))
{
size += file.Length;
}
+ return ResultManager.ToReadableSize(size, 2);
}
- catch (Exception)
+ catch (Exception e)
{
+ Main.Context.API.LogException(ClassName, $"Failed to get folder size for {folderPath}", e);
return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
}
- return ResultManager.ToReadableSize(size, 2);
}
public static string GetFolderCreatedAt(string folderPath, string previewPanelDateFormat, string previewPanelTimeFormat, bool showFileAgeInPreviewPanel)
{
- var createdDate = Directory.GetCreationTime(folderPath);
- var formattedDate = createdDate.ToString(
- $"{previewPanelDateFormat} {previewPanelTimeFormat}",
- CultureInfo.CurrentCulture
- );
+ try
+ {
+ var createdDate = Directory.GetCreationTime(folderPath);
+ var formattedDate = createdDate.ToString(
+ $"{previewPanelDateFormat} {previewPanelTimeFormat}",
+ CultureInfo.CurrentCulture
+ );
- var result = formattedDate;
- if (showFileAgeInPreviewPanel) result = $"{GetFileAge(createdDate)} - {formattedDate}";
- return result;
+ var result = formattedDate;
+ if (showFileAgeInPreviewPanel) result = $"{GetFileAge(createdDate)} - {formattedDate}";
+ return result;
+ }
+ catch (Exception e)
+ {
+ Main.Context.API.LogException(ClassName, $"Failed to get folder created date for {folderPath}", e);
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
}
public static string GetFolderLastModifiedAt(string folderPath, string previewPanelDateFormat, string previewPanelTimeFormat, bool showFileAgeInPreviewPanel)
{
- var lastModifiedDate = Directory.GetLastWriteTime(folderPath);
- var formattedDate = lastModifiedDate.ToString(
- $"{previewPanelDateFormat} {previewPanelTimeFormat}",
- CultureInfo.CurrentCulture
- );
+ try
+ {
+ var lastModifiedDate = Directory.GetLastWriteTime(folderPath);
+ var formattedDate = lastModifiedDate.ToString(
+ $"{previewPanelDateFormat} {previewPanelTimeFormat}",
+ CultureInfo.CurrentCulture
+ );
- var result = formattedDate;
- if (showFileAgeInPreviewPanel) result = $"{GetFileAge(lastModifiedDate)} - {formattedDate}";
- return result;
+ var result = formattedDate;
+ if (showFileAgeInPreviewPanel) result = $"{GetFileAge(lastModifiedDate)} - {formattedDate}";
+ return result;
+ }
+ catch (Exception e)
+ {
+ Main.Context.API.LogException(ClassName, $"Failed to get folder modified date for {folderPath}", e);
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
}
private static string GetFileAge(DateTime fileDateTime)
From edb4d743e9d193624871d1522a53c775ee2f1fa2 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 4 Jun 2025 17:36:37 +0800
Subject: [PATCH 1399/1697] Add timeout for folder size calculation
---
.../Views/PreviewPanel.xaml.cs | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
index f4d7f8436..a427a0a42 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
@@ -3,6 +3,7 @@ using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Runtime.CompilerServices;
+using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
@@ -149,8 +150,15 @@ public partial class PreviewPanel : UserControl, INotifyPropertyChanged
{
var directoryInfo = new DirectoryInfo(folderPath);
long size = 0;
+ var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(3));
foreach (var file in directoryInfo.GetFiles("*", SearchOption.AllDirectories))
{
+ if (cancellationTokenSource.Token.IsCancellationRequested)
+ {
+ // Timeout occurred, return unknown size
+ cancellationTokenSource.Dispose();
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
size += file.Length;
}
return ResultManager.ToReadableSize(size, 2);
From f2a7536298965fd77d83ba74e4af83750b7143bf Mon Sep 17 00:00:00 2001
From: Jack Ye <1160210343@qq.com>
Date: Wed, 4 Jun 2025 17:42:56 +0800
Subject: [PATCH 1400/1697] Use EnumerateFiles instead of GetFiles
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
.../Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
index a427a0a42..80c99ab9f 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
@@ -151,7 +151,7 @@ public partial class PreviewPanel : UserControl, INotifyPropertyChanged
var directoryInfo = new DirectoryInfo(folderPath);
long size = 0;
var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(3));
- foreach (var file in directoryInfo.GetFiles("*", SearchOption.AllDirectories))
+ foreach (var file in directoryInfo.EnumerateFiles("*", SearchOption.AllDirectories))
{
if (cancellationTokenSource.Token.IsCancellationRequested)
{
From 32b75b4a4fcbc1039be92d55535049e0b0eaa05b Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 4 Jun 2025 17:44:24 +0800
Subject: [PATCH 1401/1697] Fix CancellationTokenSource dispose state
---
.../Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
index 80c99ab9f..a3a0ad0aa 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
@@ -150,13 +150,12 @@ public partial class PreviewPanel : UserControl, INotifyPropertyChanged
{
var directoryInfo = new DirectoryInfo(folderPath);
long size = 0;
- var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(3));
+ using var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(3));
foreach (var file in directoryInfo.EnumerateFiles("*", SearchOption.AllDirectories))
{
if (cancellationTokenSource.Token.IsCancellationRequested)
{
// Timeout occurred, return unknown size
- cancellationTokenSource.Dispose();
return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
}
size += file.Length;
From f4d6ef371a7738924b3c6a3ee857ce76544e1482 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 4 Jun 2025 18:57:20 +0800
Subject: [PATCH 1402/1697] Fix typos
---
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 bc82c2e8f..b4a6b47b7 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -390,9 +390,9 @@ namespace Flow.Launcher
}
}
- private void OpenUri(Uri uri, bool? inPrivate = null, bool forceBrower = false)
+ private void OpenUri(Uri uri, bool? inPrivate = null, bool forceBrowser = false)
{
- if (forceBrower || uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps)
+ if (forceBrowser || uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps)
{
var browserInfo = _settings.CustomBrowser;
From 32ae3a1b67989ae00bb47ccb26579ee82a36f001 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 4 Jun 2025 22:21:08 +0800
Subject: [PATCH 1403/1697] Improve code quality
---
Flow.Launcher.Plugin/SharedCommands/SearchWeb.cs | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/Flow.Launcher.Plugin/SharedCommands/SearchWeb.cs b/Flow.Launcher.Plugin/SharedCommands/SearchWeb.cs
index 752c85933..7c4c3de79 100644
--- a/Flow.Launcher.Plugin/SharedCommands/SearchWeb.cs
+++ b/Flow.Launcher.Plugin/SharedCommands/SearchWeb.cs
@@ -1,8 +1,9 @@
-using Microsoft.Win32;
-using System;
+using System;
+using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
+using Microsoft.Win32;
namespace Flow.Launcher.Plugin.SharedCommands
{
@@ -13,7 +14,7 @@ namespace Flow.Launcher.Plugin.SharedCommands
{
private static string GetDefaultBrowserPath()
{
- string name = string.Empty;
+ var name = string.Empty;
try
{
using var regDefault = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\http\\UserChoice", false);
@@ -23,8 +24,7 @@ namespace Flow.Launcher.Plugin.SharedCommands
name = regKey.GetValue(null).ToString().ToLower().Replace("\"", "");
if (!name.EndsWith("exe"))
- name = name.Substring(0, name.LastIndexOf(".exe") + 4);
-
+ name = name[..(name.LastIndexOf(".exe") + 4)];
}
catch
{
@@ -65,7 +65,8 @@ namespace Flow.Launcher.Plugin.SharedCommands
{
Process.Start(psi)?.Dispose();
}
- catch (System.ComponentModel.Win32Exception)
+ // This error may be thrown if browser path is incorrect
+ catch (Win32Exception)
{
Process.Start(new ProcessStartInfo
{
@@ -100,7 +101,7 @@ namespace Flow.Launcher.Plugin.SharedCommands
Process.Start(psi)?.Dispose();
}
// This error may be thrown if browser path is incorrect
- catch (System.ComponentModel.Win32Exception)
+ catch (Win32Exception)
{
Process.Start(new ProcessStartInfo
{
From 4bc34f64e84f3e8eb306ac1743b6cd4b2725cb32 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 4 Jun 2025 22:22:02 +0800
Subject: [PATCH 1404/1697] Re-throw the exception if we cannot open the URL in
the default browser
---
.../SharedCommands/SearchWeb.cs | 28 +++++++++++++++----
1 file changed, 22 insertions(+), 6 deletions(-)
diff --git a/Flow.Launcher.Plugin/SharedCommands/SearchWeb.cs b/Flow.Launcher.Plugin/SharedCommands/SearchWeb.cs
index 7c4c3de79..ed3e91daf 100644
--- a/Flow.Launcher.Plugin/SharedCommands/SearchWeb.cs
+++ b/Flow.Launcher.Plugin/SharedCommands/SearchWeb.cs
@@ -68,10 +68,18 @@ namespace Flow.Launcher.Plugin.SharedCommands
// This error may be thrown if browser path is incorrect
catch (Win32Exception)
{
- Process.Start(new ProcessStartInfo
+ try
{
- FileName = url, UseShellExecute = true
- });
+ Process.Start(new ProcessStartInfo
+ {
+ FileName = url,
+ UseShellExecute = true
+ });
+ }
+ catch
+ {
+ throw; // Re-throw the exception if we cannot open the URL in the default browser
+ }
}
}
@@ -103,10 +111,18 @@ namespace Flow.Launcher.Plugin.SharedCommands
// This error may be thrown if browser path is incorrect
catch (Win32Exception)
{
- Process.Start(new ProcessStartInfo
+ try
{
- FileName = url, UseShellExecute = true
- });
+ Process.Start(new ProcessStartInfo
+ {
+ FileName = url,
+ UseShellExecute = true
+ });
+ }
+ catch
+ {
+ throw; // Re-throw the exception if we cannot open the URL in the default browser
+ }
}
}
}
From f6c75c21072b35bbc35e38dbe05adf287a2e164f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 4 Jun 2025 22:29:45 +0800
Subject: [PATCH 1405/1697] Handle exception from OpenInBrowserTab &
OpenInBrowserWindow
---
Flow.Launcher/Languages/en.xaml | 1 +
Flow.Launcher/PublicAPIInstance.cs | 22 ++++++++++++++++++----
2 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 28673c753..ec1d5bc93 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -473,6 +473,7 @@
Error
An error occurred while opening the folder. {0}
+ An error occurred while opening the url in browser. Please check your setting in Default Web Browser of general page.
Please wait...
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 7f0b03445..80d5de53d 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -399,13 +399,27 @@ namespace Flow.Launcher
var path = browserInfo.Path == "*" ? "" : browserInfo.Path;
- if (browserInfo.OpenInTab)
+ try
{
- uri.AbsoluteUri.OpenInBrowserTab(path, inPrivate ?? browserInfo.EnablePrivate, browserInfo.PrivateArg);
+ if (browserInfo.OpenInTab)
+ {
+ uri.AbsoluteUri.OpenInBrowserTab(path, inPrivate ?? browserInfo.EnablePrivate, browserInfo.PrivateArg);
+ }
+ else
+ {
+ uri.AbsoluteUri.OpenInBrowserWindow(path, inPrivate ?? browserInfo.EnablePrivate, browserInfo.PrivateArg);
+ }
}
- else
+ catch (Exception e)
{
- uri.AbsoluteUri.OpenInBrowserWindow(path, inPrivate ?? browserInfo.EnablePrivate, browserInfo.PrivateArg);
+ var tabOrWindow = browserInfo.OpenInTab ? "tab" : "window";
+ LogException(ClassName, $"Failed to open URL in browser {tabOrWindow}: {path}, {inPrivate ?? browserInfo.EnablePrivate}, {browserInfo.PrivateArg}", e);
+ ShowMsgBox(
+ GetTranslation("browserOpenError"),
+ GetTranslation("errorTitle"),
+ MessageBoxButton.OK,
+ MessageBoxImage.Error
+ );
}
}
else
From 2f8e5b91b0666a366e012b56ba614caaaa6be892 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 4 Jun 2025 23:17:38 +0800
Subject: [PATCH 1406/1697] Add new setting to enable favorite icons
---
.../Languages/en.xaml | 2 ++
.../Models/Settings.cs | 2 ++
.../Views/SettingsControl.xaml | 8 ++++++++
3 files changed, 12 insertions(+)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/en.xaml
index e5f3d541e..861779a3d 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/en.xaml
@@ -27,4 +27,6 @@
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.
+ Load favorite icons (It may cost much time)
+
\ No newline at end of file
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Models/Settings.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Models/Settings.cs
index 86532d275..44993aec9 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Models/Settings.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Models/Settings.cs
@@ -8,6 +8,8 @@ public class Settings : BaseModel
public string BrowserPath { get; set; }
+ public bool EnableFavoriteIcons { get; set; } = false;
+
public bool LoadChromeBookmark { get; set; } = true;
public bool LoadFirefoxBookmark { get; set; } = true;
public bool LoadEdgeBookmark { get; set; } = true;
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml
index 30424f4e8..fef60eea4 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml
@@ -12,6 +12,7 @@
+
+
\ No newline at end of file
From fd8222ba8075a2412bebe2d40a443dca9378cfb5 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 4 Jun 2025 23:17:51 +0800
Subject: [PATCH 1407/1697] Organize usings
---
Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs
index 155069495..c08a508d3 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs
@@ -1,14 +1,14 @@
using System;
using System.Collections.Generic;
+using System.IO;
using System.Linq;
+using System.Threading.Channels;
+using System.Threading.Tasks;
+using System.Threading;
using System.Windows.Controls;
using Flow.Launcher.Plugin.BrowserBookmark.Commands;
using Flow.Launcher.Plugin.BrowserBookmark.Models;
using Flow.Launcher.Plugin.BrowserBookmark.Views;
-using System.IO;
-using System.Threading.Channels;
-using System.Threading.Tasks;
-using System.Threading;
using Flow.Launcher.Plugin.SharedCommands;
namespace Flow.Launcher.Plugin.BrowserBookmark;
From cef3e8e4bb8ecdd0da22f91178382421d298ee2f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 4 Jun 2025 23:18:01 +0800
Subject: [PATCH 1408/1697] Make settings internal
---
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 c08a508d3..91ade206b 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs
@@ -21,9 +21,9 @@ public class Main : ISettingProvider, IPlugin, IReloadable, IPluginI18n, IContex
internal static PluginInitContext _context;
- private static List _cachedBookmarks = new();
+ internal static Settings _settings;
- private static Settings _settings;
+ private static List _cachedBookmarks = new();
private static bool _initialized = false;
From f982d80ffe66bb6ab3b0e03fda14896173f204e6 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 4 Jun 2025 23:21:57 +0800
Subject: [PATCH 1409/1697] Support enable favorite icons for chromiun
bookmarks
---
.../ChromiumBookmarkLoader.cs | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
index e859976bd..b8874c94a 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
@@ -43,16 +43,20 @@ public abstract class ChromiumBookmarkLoader : IBookmarkLoader
catch (Exception ex)
{
Main._context.API.LogException(ClassName, $"Failed to register bookmark file monitoring: {bookmarkPath}", ex);
+ continue;
}
var source = name + (Path.GetFileName(profile) == "Default" ? "" : $" ({Path.GetFileName(profile)})");
var profileBookmarks = LoadBookmarksFromFile(bookmarkPath, source);
// Load favicons after loading bookmarks
- var faviconDbPath = Path.Combine(profile, "Favicons");
- if (File.Exists(faviconDbPath))
+ if (Main._settings.EnableFavoriteIcons)
{
- LoadFaviconsFromDb(faviconDbPath, profileBookmarks);
+ var faviconDbPath = Path.Combine(profile, "Favicons");
+ if (File.Exists(faviconDbPath))
+ {
+ LoadFaviconsFromDb(faviconDbPath, profileBookmarks);
+ }
}
bookmarks.AddRange(profileBookmarks);
From b68b299cd49271013e5f31f3bed4203076da9437 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 4 Jun 2025 23:26:32 +0800
Subject: [PATCH 1410/1697] Support enable favorite icons for firefox bookmarks
---
.../FirefoxBookmarkLoader.cs | 39 +++++++++++--------
1 file changed, 23 insertions(+), 16 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
index 75f26d322..5cbd92586 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
@@ -41,30 +41,33 @@ public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader
if (string.IsNullOrEmpty(placesPath) || !File.Exists(placesPath))
return bookmarks;
+ // Try to register file monitoring
+ try
+ {
+ Main.RegisterBookmarkFile(placesPath);
+ }
+ catch (Exception ex)
+ {
+ Main._context.API.LogException(ClassName, $"Failed to register Firefox bookmark file monitoring: {placesPath}", ex);
+ return bookmarks;
+ }
+
var tempDbPath = Path.Combine(_faviconCacheDir, $"tempplaces_{Guid.NewGuid()}.sqlite");
try
{
- // Try to register file monitoring
- try
- {
- Main.RegisterBookmarkFile(placesPath);
- }
- catch (Exception 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
File.Copy(placesPath, tempDbPath, true);
- // Connect to database and execute query
+ // Create the connection string and init the connection
string dbPath = string.Format(DbPathFormat, tempDbPath);
using var dbConnection = new SqliteConnection(dbPath);
+
+ // Open connection to the database file and execute the query
dbConnection.Open();
var reader = new SqliteCommand(QueryAllBookmarks, dbConnection).ExecuteReader();
- // Create bookmark list
+ // Get results in List format
bookmarks = reader
.Select(
x => new Bookmark(
@@ -75,12 +78,16 @@ public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader
)
.ToList();
- // Path to favicon database
- var faviconDbPath = Path.Combine(Path.GetDirectoryName(placesPath), "favicons.sqlite");
- if (File.Exists(faviconDbPath))
+ // Load favicons after loading bookmarks
+ if (Main._settings.EnableFavoriteIcons)
{
- LoadFaviconsFromDb(faviconDbPath, bookmarks);
+ var faviconDbPath = Path.Combine(Path.GetDirectoryName(placesPath), "favicons.sqlite");
+ if (File.Exists(faviconDbPath))
+ {
+ LoadFaviconsFromDb(faviconDbPath, bookmarks);
+ }
}
+
// https://github.com/dotnet/efcore/issues/26580
SqliteConnection.ClearPool(dbConnection);
dbConnection.Close();
From 6d5b95c6168ffb07fd2ffa08686eaef368ecd189 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 4 Jun 2025 23:31:10 +0800
Subject: [PATCH 1411/1697] Improve code comments
---
.../FirefoxBookmarkLoader.cs | 1 +
1 file changed, 1 insertion(+)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
index 5cbd92586..e090d8c14 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
@@ -88,6 +88,7 @@ public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader
}
}
+ // Close the connection so that we can delete the temporary file
// https://github.com/dotnet/efcore/issues/26580
SqliteConnection.ClearPool(dbConnection);
dbConnection.Close();
From a761ec880bd8de87c36771e7a2fab72f4b591bcf Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 4 Jun 2025 23:31:18 +0800
Subject: [PATCH 1412/1697] Check file exists
---
.../FirefoxBookmarkLoader.cs | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
index e090d8c14..06ddba7af 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
@@ -101,7 +101,10 @@ public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader
// Delete temporary file
try
{
- File.Delete(tempDbPath);
+ if (File.Exists(tempDbPath))
+ {
+ File.Delete(tempDbPath);
+ }
}
catch (Exception ex)
{
From 72bd4c202a194667308d3d6adb778bf9b42640b6 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 5 Jun 2025 00:27:03 +0800
Subject: [PATCH 1413/1697] Info favorite icons cost
---
.../ChromiumBookmarkLoader.cs | 5 ++++-
.../FirefoxBookmarkLoader.cs | 5 ++++-
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
index b8874c94a..16f0a0798 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
@@ -55,7 +55,10 @@ public abstract class ChromiumBookmarkLoader : IBookmarkLoader
var faviconDbPath = Path.Combine(profile, "Favicons");
if (File.Exists(faviconDbPath))
{
- LoadFaviconsFromDb(faviconDbPath, profileBookmarks);
+ Main._context.API.StopwatchLogInfo(ClassName, $"Load {profileBookmarks.Count} favorite icons cost", () =>
+ {
+ LoadFaviconsFromDb(faviconDbPath, profileBookmarks);
+ });
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
index 06ddba7af..d387cd7b5 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
@@ -84,7 +84,10 @@ public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader
var faviconDbPath = Path.Combine(Path.GetDirectoryName(placesPath), "favicons.sqlite");
if (File.Exists(faviconDbPath))
{
- LoadFaviconsFromDb(faviconDbPath, bookmarks);
+ Main._context.API.StopwatchLogInfo(ClassName, $"Load {bookmarks.Count} favorite icons cost", () =>
+ {
+ LoadFaviconsFromDb(faviconDbPath, bookmarks);
+ });
}
}
From 0ec38faf1deb008ece5ae41868bf5347488381c5 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 5 Jun 2025 01:12:12 +0800
Subject: [PATCH 1414/1697] Add code comments & Improve code quality
---
.../ChromiumBookmarkLoader.cs | 1 +
.../FirefoxBookmarkLoader.cs | 4 +++-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
index 16f0a0798..a20baccb5 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
@@ -132,6 +132,7 @@ public abstract class ChromiumBookmarkLoader : IBookmarkLoader
// Use a copy to avoid lock issues with the original file
var tempDbPath = Path.Combine(_faviconCacheDir, $"tempfavicons_{Guid.NewGuid()}.db");
+ // Use a copy to avoid lock issues with the original file
try
{
File.Copy(dbPath, tempDbPath, true);
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
index d387cd7b5..11fc688e7 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
@@ -60,7 +60,7 @@ public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader
File.Copy(placesPath, tempDbPath, true);
// Create the connection string and init the connection
- string dbPath = string.Format(DbPathFormat, tempDbPath);
+ var dbPath = string.Format($"Data Source={tempDbPath};Mode=ReadOnly");
using var dbConnection = new SqliteConnection(dbPath);
// Open connection to the database file and execute the query
@@ -119,8 +119,10 @@ public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader
private void LoadFaviconsFromDb(string faviconDbPath, List bookmarks)
{
+ // Use a copy to avoid lock issues with the original file
var tempDbPath = Path.Combine(_faviconCacheDir, $"tempfavicons_{Guid.NewGuid()}.sqlite");
+ // Use a copy to avoid lock issues with the original file
try
{
// Use a copy to avoid lock issues with the original file
From d6f40ec488c4fd1134e3510cee52623b741fad04 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 5 Jun 2025 01:12:46 +0800
Subject: [PATCH 1415/1697] Use concurrent way to load favorite icons for
chromium
---
.../ChromiumBookmarkLoader.cs | 45 ++++++++++++-------
1 file changed, 30 insertions(+), 15 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
index a20baccb5..ddb50235c 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
@@ -1,7 +1,9 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
using System.IO;
using System.Text.Json;
-using System;
+using System.Threading.Tasks;
using Flow.Launcher.Plugin.BrowserBookmark.Models;
using Microsoft.Data.Sqlite;
@@ -156,19 +158,24 @@ public abstract class ChromiumBookmarkLoader : IBookmarkLoader
try
{
- using var connection = new SqliteConnection($"Data Source={tempDbPath}");
- connection.Open();
+ // Since some bookmarks may have same favorite icon id, we need to record them to avoid duplicates
+ var savedPaths = new ConcurrentDictionary();
- foreach (var bookmark in bookmarks)
+ // Get favicons based on bookmarks concurrently
+ Parallel.ForEach(bookmarks.ToArray(), bookmark =>
{
+ // Use read-only connection to avoid locking issues
+ var connection = new SqliteConnection($"Data Source={tempDbPath};Mode=ReadOnly");
+ connection.Open();
+
try
{
var url = bookmark.Url;
- if (string.IsNullOrEmpty(url)) continue;
+ if (string.IsNullOrEmpty(url)) return;
// Extract domain from URL
if (!Uri.TryCreate(url, UriKind.Absolute, out Uri uri))
- continue;
+ return;
var domain = uri.Host;
@@ -186,16 +193,21 @@ public abstract class ChromiumBookmarkLoader : IBookmarkLoader
using var reader = cmd.ExecuteReader();
if (!reader.Read() || reader.IsDBNull(1))
- continue;
+ return;
var iconId = reader.GetInt64(0).ToString();
var imageData = (byte[])reader["image_data"];
if (imageData is not { Length: > 0 })
- continue;
+ return;
var faviconPath = Path.Combine(_faviconCacheDir, $"chromium_{domain}_{iconId}.png");
- SaveBitmapData(imageData, faviconPath);
+
+ // Filter out duplicate favorite icons
+ if (savedPaths.TryAdd(faviconPath, true))
+ {
+ SaveBitmapData(imageData, faviconPath);
+ }
bookmark.FaviconPath = faviconPath;
}
@@ -203,11 +215,14 @@ public abstract class ChromiumBookmarkLoader : IBookmarkLoader
{
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();
+ finally
+ {
+ // https://github.com/dotnet/efcore/issues/26580
+ SqliteConnection.ClearPool(connection);
+ connection.Close();
+ connection.Dispose();
+ }
+ });
}
catch (Exception ex)
{
From 8bb2b50a4c11ebe71211e908c423c47f2185c1bc Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 5 Jun 2025 01:13:48 +0800
Subject: [PATCH 1416/1697] Use concurrent way to load favorite icons for
firefox
---
.../FirefoxBookmarkLoader.cs | 79 ++++++++++++-------
1 file changed, 52 insertions(+), 27 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
index 11fc688e7..5d6854aa5 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
@@ -1,7 +1,9 @@
using System;
+using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Threading.Tasks;
using Flow.Launcher.Plugin.BrowserBookmark.Models;
using Microsoft.Data.Sqlite;
@@ -30,8 +32,6 @@ public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader
ORDER BY moz_places.visit_count DESC
""";
- private const string DbPathFormat = "Data Source={0}";
-
protected List GetBookmarksFromPath(string placesPath)
{
// Variable to store bookmark list
@@ -117,7 +117,7 @@ public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader
return bookmarks;
}
- private void LoadFaviconsFromDb(string faviconDbPath, List bookmarks)
+ 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()}.sqlite");
@@ -125,28 +125,45 @@ public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader
// Use a copy to avoid lock issues with the original file
try
{
- // Use a copy to avoid lock issues with the original file
- File.Copy(faviconDbPath, tempDbPath, true);
-
- var defaultIconPath = Path.Combine(
- Path.GetDirectoryName(typeof(FirefoxBookmarkLoaderBase).Assembly.Location),
- "bookmark.png");
-
- string dbPath = string.Format(DbPathFormat, tempDbPath);
- using var connection = new SqliteConnection(dbPath);
- connection.Open();
-
- // Get favicons based on bookmark URLs
- foreach (var bookmark in bookmarks)
+ File.Copy(dbPath, tempDbPath, true);
+ }
+ catch (Exception ex)
+ {
+ 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;
+ }
+
+ try
+ {
+ // Since some bookmarks may have same favorite icon id, we need to record them to avoid duplicates
+ var savedPaths = new ConcurrentDictionary();
+
+ // Get favicons based on bookmarks concurrently
+ Parallel.ForEach(bookmarks, bookmark =>
+ {
+ // Use read-only connection to avoid locking issues
+ var connection = new SqliteConnection($"Data Source={tempDbPath};Mode=ReadOnly");
+ connection.Open();
+
try
{
if (string.IsNullOrEmpty(bookmark.Url))
- continue;
+ return;
// Extract domain from URL
if (!Uri.TryCreate(bookmark.Url, UriKind.Absolute, out Uri uri))
- continue;
+ return;
var domain = uri.Host;
@@ -166,12 +183,12 @@ public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader
using var reader = cmd.ExecuteReader();
if (!reader.Read() || reader.IsDBNull(0))
- continue;
+ return;
var imageData = (byte[])reader["data"];
if (imageData is not { Length: > 0 })
- continue;
+ return;
string faviconPath;
if (IsSvgData(imageData))
@@ -182,7 +199,12 @@ public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader
{
faviconPath = Path.Combine(_faviconCacheDir, $"firefox_{domain}.png");
}
- SaveBitmapData(imageData, faviconPath);
+
+ // Filter out duplicate favorite icons
+ if (savedPaths.TryAdd(faviconPath, true))
+ {
+ SaveBitmapData(imageData, faviconPath);
+ }
bookmark.FaviconPath = faviconPath;
}
@@ -190,15 +212,18 @@ public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader
{
Main._context.API.LogException(ClassName, $"Failed to extract Firefox favicon: {bookmark.Url}", ex);
}
- }
-
- // https://github.com/dotnet/efcore/issues/26580
- SqliteConnection.ClearPool(connection);
- connection.Close();
+ finally
+ {
+ // https://github.com/dotnet/efcore/issues/26580
+ SqliteConnection.ClearPool(connection);
+ connection.Close();
+ connection.Dispose();
+ }
+ });
}
catch (Exception ex)
{
- Main._context.API.LogException(ClassName, $"Failed to load Firefox favicon DB: {faviconDbPath}", ex);
+ Main._context.API.LogException(ClassName, $"Failed to load Firefox favicon DB: {tempDbPath}", ex);
}
// Delete temporary file
From f717376a1745db848a5f3427ca67dc53fb372dab Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 5 Jun 2025 01:30:26 +0800
Subject: [PATCH 1417/1697] Remove dulplicated comments
---
.../ChromiumBookmarkLoader.cs | 1 -
.../FirefoxBookmarkLoader.cs | 1 -
2 files changed, 2 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
index ddb50235c..8a23cc8fd 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
@@ -134,7 +134,6 @@ public abstract class ChromiumBookmarkLoader : IBookmarkLoader
// Use a copy to avoid lock issues with the original file
var tempDbPath = Path.Combine(_faviconCacheDir, $"tempfavicons_{Guid.NewGuid()}.db");
- // Use a copy to avoid lock issues with the original file
try
{
File.Copy(dbPath, tempDbPath, true);
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
index 5d6854aa5..62b71da4c 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
@@ -122,7 +122,6 @@ public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader
// Use a copy to avoid lock issues with the original file
var tempDbPath = Path.Combine(_faviconCacheDir, $"tempfavicons_{Guid.NewGuid()}.sqlite");
- // Use a copy to avoid lock issues with the original file
try
{
File.Copy(dbPath, tempDbPath, true);
From 49a42dd1b45d107b14fbdec7a4f36bf2e9db35d1 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 5 Jun 2025 01:31:06 +0800
Subject: [PATCH 1418/1697] Improve code quality
---
.../FirefoxBookmarkLoader.cs | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
index 62b71da4c..cd2f40d58 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
@@ -60,8 +60,7 @@ public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader
File.Copy(placesPath, tempDbPath, true);
// Create the connection string and init the connection
- var dbPath = string.Format($"Data Source={tempDbPath};Mode=ReadOnly");
- using var dbConnection = new SqliteConnection(dbPath);
+ using var dbConnection = new SqliteConnection($"Data Source={tempDbPath};Mode=ReadOnly");
// Open connection to the database file and execute the query
dbConnection.Open();
From 76dc35433bfed913d460bfdfc92f83bf71d9d393 Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Thu, 5 Jun 2025 12:12:55 +1000
Subject: [PATCH 1419/1697] update wording
---
Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/en.xaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/en.xaml
index 861779a3d..44118c099 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/en.xaml
@@ -27,6 +27,6 @@
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.
- Load favorite icons (It may cost much time)
+ Load favorite icons (can be time consuming during startup)
\ No newline at end of file
From d87a7ce32beed41f45bb765a87965304f2df65ed Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Thu, 5 Jun 2025 12:15:47 +1000
Subject: [PATCH 1420/1697] use favicons instead of favourite icons
---
Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/en.xaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/en.xaml
index 44118c099..a133d2402 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/en.xaml
@@ -27,6 +27,6 @@
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.
- Load favorite icons (can be time consuming during startup)
+ Load favicons (can be time consuming during startup)
\ No newline at end of file
From 69dd0383115e52b2ffacc275756b4a353f47b1d2 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 5 Jun 2025 10:16:02 +0800
Subject: [PATCH 1421/1697] No need to convert to array
---
.../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 8a23cc8fd..cbcbf70ea 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
@@ -161,7 +161,7 @@ public abstract class ChromiumBookmarkLoader : IBookmarkLoader
var savedPaths = new ConcurrentDictionary();
// Get favicons based on bookmarks concurrently
- Parallel.ForEach(bookmarks.ToArray(), bookmark =>
+ Parallel.ForEach(bookmarks, bookmark =>
{
// Use read-only connection to avoid locking issues
var connection = new SqliteConnection($"Data Source={tempDbPath};Mode=ReadOnly");
From 94b8a66db73f547f660580d77471f3cb5854d1c9 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 5 Jun 2025 10:21:24 +0800
Subject: [PATCH 1422/1697] Rename to favicon
---
.../ChromiumBookmarkLoader.cs | 8 ++++----
.../FirefoxBookmarkLoader.cs | 8 ++++----
.../Languages/en.xaml | 2 +-
.../Models/Settings.cs | 2 +-
.../Views/SettingsControl.xaml | 4 ++--
5 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
index cbcbf70ea..e102e43b6 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
@@ -52,12 +52,12 @@ public abstract class ChromiumBookmarkLoader : IBookmarkLoader
var profileBookmarks = LoadBookmarksFromFile(bookmarkPath, source);
// Load favicons after loading bookmarks
- if (Main._settings.EnableFavoriteIcons)
+ if (Main._settings.EnableFavicons)
{
var faviconDbPath = Path.Combine(profile, "Favicons");
if (File.Exists(faviconDbPath))
{
- Main._context.API.StopwatchLogInfo(ClassName, $"Load {profileBookmarks.Count} favorite icons cost", () =>
+ Main._context.API.StopwatchLogInfo(ClassName, $"Load {profileBookmarks.Count} favicons cost", () =>
{
LoadFaviconsFromDb(faviconDbPath, profileBookmarks);
});
@@ -157,7 +157,7 @@ public abstract class ChromiumBookmarkLoader : IBookmarkLoader
try
{
- // Since some bookmarks may have same favorite icon id, we need to record them to avoid duplicates
+ // Since some bookmarks may have same favicon id, we need to record them to avoid duplicates
var savedPaths = new ConcurrentDictionary();
// Get favicons based on bookmarks concurrently
@@ -202,7 +202,7 @@ public abstract class ChromiumBookmarkLoader : IBookmarkLoader
var faviconPath = Path.Combine(_faviconCacheDir, $"chromium_{domain}_{iconId}.png");
- // Filter out duplicate favorite icons
+ // Filter out duplicate favicons
if (savedPaths.TryAdd(faviconPath, true))
{
SaveBitmapData(imageData, faviconPath);
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
index cd2f40d58..492a76c7b 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
@@ -78,12 +78,12 @@ public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader
.ToList();
// Load favicons after loading bookmarks
- if (Main._settings.EnableFavoriteIcons)
+ if (Main._settings.EnableFavicons)
{
var faviconDbPath = Path.Combine(Path.GetDirectoryName(placesPath), "favicons.sqlite");
if (File.Exists(faviconDbPath))
{
- Main._context.API.StopwatchLogInfo(ClassName, $"Load {bookmarks.Count} favorite icons cost", () =>
+ Main._context.API.StopwatchLogInfo(ClassName, $"Load {bookmarks.Count} favicons cost", () =>
{
LoadFaviconsFromDb(faviconDbPath, bookmarks);
});
@@ -144,7 +144,7 @@ public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader
try
{
- // Since some bookmarks may have same favorite icon id, we need to record them to avoid duplicates
+ // Since some bookmarks may have same favicon id, we need to record them to avoid duplicates
var savedPaths = new ConcurrentDictionary();
// Get favicons based on bookmarks concurrently
@@ -198,7 +198,7 @@ public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader
faviconPath = Path.Combine(_faviconCacheDir, $"firefox_{domain}.png");
}
- // Filter out duplicate favorite icons
+ // Filter out duplicate favicons
if (savedPaths.TryAdd(faviconPath, true))
{
SaveBitmapData(imageData, faviconPath);
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/en.xaml
index a133d2402..22830e7c8 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/en.xaml
@@ -27,6 +27,6 @@
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.
- Load favicons (can be time consuming during startup)
+ Load favicons (can be time consuming during startup)
\ No newline at end of file
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Models/Settings.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Models/Settings.cs
index 44993aec9..a0041e0d6 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Models/Settings.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Models/Settings.cs
@@ -8,7 +8,7 @@ public class Settings : BaseModel
public string BrowserPath { get; set; }
- public bool EnableFavoriteIcons { get; set; } = false;
+ public bool EnableFavicons { get; set; } = false;
public bool LoadChromeBookmark { get; set; } = true;
public bool LoadFirefoxBookmark { get; set; } = true;
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml
index fef60eea4..0767ee980 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml
@@ -97,7 +97,7 @@
Margin="{StaticResource SettingPanelItemTopBottomMargin}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
- Content="{DynamicResource flowlauncher_plugin_browserbookmark_enable_favorite_icons}"
- IsChecked="{Binding Settings.EnableFavoriteIcons}" />
+ Content="{DynamicResource flowlauncher_plugin_browserbookmark_enable_favicons}"
+ IsChecked="{Binding Settings.EnableFavicons}" />
\ No newline at end of file
From 25a62c8700b8fb4ed14a0f934e742ea979a87757 Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Thu, 5 Jun 2025 12:46:46 +1000
Subject: [PATCH 1423/1697] fix wording
---
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 ec1d5bc93..c9fc36892 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -473,7 +473,7 @@
Error
An error occurred while opening the folder. {0}
- An error occurred while opening the url in browser. Please check your setting in Default Web Browser of general page.
+ An error occurred while opening the URL in the browser. Please check your Default Web Browser configuration in the General section of the settings window
Please wait...
From e61151dc437bf62deb92291302ecc88b1ea1a780 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 5 Jun 2025 11:18:07 +0800
Subject: [PATCH 1424/1697] Improve preview panel performance
---
.../Views/PreviewPanel.xaml | 2 +-
.../Views/PreviewPanel.xaml.cs | 15 +++++++++++++--
2 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml
index 22aa8f597..e200a187f 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml
@@ -117,7 +117,7 @@
HorizontalAlignment="Right"
VerticalAlignment="Top"
Style="{DynamicResource PreviewItemSubTitleStyle}"
- Text="{Binding FileSize, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}"
+ Text="{Binding FileSize, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}, Mode=OneWay}"
TextWrapping="Wrap"
Visibility="{Binding FileSizeVisibility, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}" />
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
index a3a0ad0aa..ec60a3c13 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
@@ -20,7 +20,7 @@ public partial class PreviewPanel : UserControl, INotifyPropertyChanged
private static readonly string ClassName = nameof(PreviewPanel);
private string FilePath { get; }
- public string FileSize { get; } = "";
+ public string FileSize { get; private set; } = Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
public string CreatedAt { get; } = "";
public string LastModifiedAt { get; } = "";
private ImageSource _previewImage = new BitmapImage();
@@ -63,7 +63,18 @@ public partial class PreviewPanel : UserControl, INotifyPropertyChanged
if (Settings.ShowFileSizeInPreviewPanel)
{
- FileSize = type == ResultType.File ? GetFileSize(filePath) : GetFolderSize(filePath);
+ if (type == ResultType.File)
+ {
+ FileSize = GetFileSize(filePath);
+ }
+ else
+ {
+ _ = Task.Run(() =>
+ {
+ FileSize = GetFolderSize(filePath);
+ OnPropertyChanged(nameof(FileSize));
+ }).ConfigureAwait(false);
+ }
}
if (Settings.ShowCreatedDateInPreviewPanel)
From 19061df586b2d2d37b3757fb4ef25eb0d931cec3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 5 Jun 2025 11:24:20 +0800
Subject: [PATCH 1425/1697] Use concurrent version
---
.../Views/PreviewPanel.xaml.cs | 24 ++++++++++---------
1 file changed, 13 insertions(+), 11 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
index ec60a3c13..5c250c8a8 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
@@ -2,6 +2,7 @@
using System.ComponentModel;
using System.Globalization;
using System.IO;
+using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
@@ -157,22 +158,23 @@ public partial class PreviewPanel : UserControl, INotifyPropertyChanged
public static string GetFolderSize(string folderPath)
{
+ using var timeoutCts = new CancellationTokenSource(TimeSpan.FromSeconds(3));
+
try
{
+ // Use parallel enumeration for better performance
var directoryInfo = new DirectoryInfo(folderPath);
- long size = 0;
- using var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(3));
- foreach (var file in directoryInfo.EnumerateFiles("*", SearchOption.AllDirectories))
- {
- if (cancellationTokenSource.Token.IsCancellationRequested)
- {
- // Timeout occurred, return unknown size
- return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
- }
- size += file.Length;
- }
+ long size = directoryInfo.EnumerateFiles("*", SearchOption.AllDirectories)
+ .AsParallel()
+ .WithCancellation(timeoutCts.Token)
+ .Sum(file => file.Length);
+
return ResultManager.ToReadableSize(size, 2);
}
+ catch (OperationCanceledException)
+ {
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
catch (Exception e)
{
Main.Context.API.LogException(ClassName, $"Failed to get folder size for {folderPath}", e);
From 617c62f6c6ee5c87ab4356d5af9d03bec134e25d Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 5 Jun 2025 11:25:48 +0800
Subject: [PATCH 1426/1697] Add error log message
---
Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs | 1 +
1 file changed, 1 insertion(+)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
index 5c250c8a8..e4a9e5bb2 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
@@ -173,6 +173,7 @@ public partial class PreviewPanel : UserControl, INotifyPropertyChanged
}
catch (OperationCanceledException)
{
+ Main.Context.API.LogError(ClassName, $"Operation timed out while calculating folder size for {folderPath}");
return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
}
catch (Exception e)
From 14ffe3c6757f086dc4fbd360caa4f70801ad82d2 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 5 Jun 2025 11:38:08 +0800
Subject: [PATCH 1427/1697] Handle more exceptions
---
.../Views/PreviewPanel.xaml.cs | 60 +++++++++++++++++++
1 file changed, 60 insertions(+)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
index e4a9e5bb2..5c0832871 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
@@ -107,6 +107,16 @@ public partial class PreviewPanel : UserControl, INotifyPropertyChanged
var fileInfo = new FileInfo(filePath);
return ResultManager.ToReadableSize(fileInfo.Length, 2);
}
+ catch (FileNotFoundException)
+ {
+ Main.Context.API.LogError(ClassName, $"File not found: {filePath}");
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
+ catch (UnauthorizedAccessException)
+ {
+ Main.Context.API.LogError(ClassName, $"Access denied to file: {filePath}");
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
catch (Exception e)
{
Main.Context.API.LogException(ClassName, $"Failed to get file size for {filePath}", e);
@@ -128,6 +138,16 @@ public partial class PreviewPanel : UserControl, INotifyPropertyChanged
if (showFileAgeInPreviewPanel) result = $"{GetFileAge(createdDate)} - {formattedDate}";
return result;
}
+ catch (FileNotFoundException)
+ {
+ Main.Context.API.LogError(ClassName, $"File not found: {filePath}");
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
+ catch (UnauthorizedAccessException)
+ {
+ Main.Context.API.LogError(ClassName, $"Access denied to file: {filePath}");
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
catch (Exception e)
{
Main.Context.API.LogException(ClassName, $"Failed to get file created date for {filePath}", e);
@@ -149,6 +169,16 @@ public partial class PreviewPanel : UserControl, INotifyPropertyChanged
if (showFileAgeInPreviewPanel) result = $"{GetFileAge(lastModifiedDate)} - {formattedDate}";
return result;
}
+ catch (FileNotFoundException)
+ {
+ Main.Context.API.LogError(ClassName, $"File not found: {filePath}");
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
+ catch (UnauthorizedAccessException)
+ {
+ Main.Context.API.LogError(ClassName, $"Access denied to file: {filePath}");
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
catch (Exception e)
{
Main.Context.API.LogException(ClassName, $"Failed to get file modified date for {filePath}", e);
@@ -171,6 +201,16 @@ public partial class PreviewPanel : UserControl, INotifyPropertyChanged
return ResultManager.ToReadableSize(size, 2);
}
+ catch (FileNotFoundException)
+ {
+ Main.Context.API.LogError(ClassName, $"Folder not found: {folderPath}");
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
+ catch (UnauthorizedAccessException)
+ {
+ Main.Context.API.LogError(ClassName, $"Access denied to folder: {folderPath}");
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
catch (OperationCanceledException)
{
Main.Context.API.LogError(ClassName, $"Operation timed out while calculating folder size for {folderPath}");
@@ -197,6 +237,16 @@ public partial class PreviewPanel : UserControl, INotifyPropertyChanged
if (showFileAgeInPreviewPanel) result = $"{GetFileAge(createdDate)} - {formattedDate}";
return result;
}
+ catch (FileNotFoundException)
+ {
+ Main.Context.API.LogError(ClassName, $"Folder not found: {folderPath}");
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
+ catch (UnauthorizedAccessException)
+ {
+ Main.Context.API.LogError(ClassName, $"Access denied to folder: {folderPath}");
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
catch (Exception e)
{
Main.Context.API.LogException(ClassName, $"Failed to get folder created date for {folderPath}", e);
@@ -218,6 +268,16 @@ public partial class PreviewPanel : UserControl, INotifyPropertyChanged
if (showFileAgeInPreviewPanel) result = $"{GetFileAge(lastModifiedDate)} - {formattedDate}";
return result;
}
+ catch (FileNotFoundException)
+ {
+ Main.Context.API.LogError(ClassName, $"Folder not found: {folderPath}");
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
+ catch (UnauthorizedAccessException)
+ {
+ Main.Context.API.LogError(ClassName, $"Access denied to folder: {folderPath}");
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
catch (Exception e)
{
Main.Context.API.LogException(ClassName, $"Failed to get folder modified date for {folderPath}", e);
From 1a95632ddf2617c059554a95469c90d55acb70a3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 5 Jun 2025 11:45:18 +0800
Subject: [PATCH 1428/1697] Handle AggregateException
---
.../Views/PreviewPanel.xaml.cs | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
index 5c0832871..5714b0d0f 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
@@ -216,6 +216,25 @@ public partial class PreviewPanel : UserControl, INotifyPropertyChanged
Main.Context.API.LogError(ClassName, $"Operation timed out while calculating folder size for {folderPath}");
return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
}
+ // For parallel operations, AggregateException may be thrown if any of the tasks fail
+ catch (AggregateException ae)
+ {
+ switch (ae.InnerException)
+ {
+ case FileNotFoundException:
+ Main.Context.API.LogError(ClassName, $"Folder not found: {folderPath}");
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ case UnauthorizedAccessException:
+ Main.Context.API.LogError(ClassName, $"Access denied to folder: {folderPath}");
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ case OperationCanceledException:
+ Main.Context.API.LogError(ClassName, $"Operation timed out while calculating folder size for {folderPath}");
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ default:
+ Main.Context.API.LogException(ClassName, $"Failed to get folder size for {folderPath}", ae);
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
+ }
catch (Exception e)
{
Main.Context.API.LogException(ClassName, $"Failed to get folder size for {folderPath}", e);
From 4c7a4fec1f09a44887baadb4c4026019046c28b0 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 5 Jun 2025 11:56:21 +0800
Subject: [PATCH 1429/1697] Add more info tooltip support for volumes
---
.../Languages/en.xaml | 1 +
.../Search/ResultManager.cs | 79 ++++++++++---------
2 files changed, 44 insertions(+), 36 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
index 1cb050e64..f782a59fa 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
@@ -82,6 +82,7 @@
Ctrl + Enter to open the containing folder
{0}{4}Size: {1}{4}Date created: {2}{4}Date modified: {3}
Unknown
+ {0}{3}Space free: {1}{3}Total size: {2}
Copy path
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
index 4e9a376ab..6bbdcbe0a 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
@@ -162,7 +162,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
},
Score = score,
TitleToolTip = Main.Context.API.GetTranslation("plugin_explorer_plugin_ToolTipOpenDirectory"),
- SubTitleToolTip = Settings.DisplayMoreInformationInToolTip ? GetMoreInfoToolTip(path, ResultType.Folder) : path,
+ SubTitleToolTip = Settings.DisplayMoreInformationInToolTip ? GetFolderMoreInfoTooltip(path) : path,
ContextData = new SearchResult { Type = ResultType.Folder, FullPath = path, WindowsIndexed = windowsIndexed }
};
}
@@ -183,6 +183,10 @@ namespace Flow.Launcher.Plugin.Explorer.Search
if (progressValue >= 90)
progressBarColor = "#da2626";
+ var tooltip = Settings.DisplayMoreInformationInToolTip
+ ? GetVolumeMoreInfoTooltip(path, freespace, totalspace)
+ : path;
+
return new Result
{
Title = title,
@@ -201,8 +205,8 @@ namespace Flow.Launcher.Plugin.Explorer.Search
OpenFolder(path);
return true;
},
- TitleToolTip = path,
- SubTitleToolTip = path,
+ TitleToolTip = tooltip,
+ SubTitleToolTip = tooltip,
ContextData = new SearchResult { Type = ResultType.Volume, FullPath = path, WindowsIndexed = windowsIndexed }
};
}
@@ -316,7 +320,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
return true;
},
TitleToolTip = Main.Context.API.GetTranslation("plugin_explorer_plugin_ToolTipOpenContainingFolder"),
- SubTitleToolTip = Settings.DisplayMoreInformationInToolTip ? GetMoreInfoToolTip(filePath, ResultType.File) : filePath,
+ SubTitleToolTip = Settings.DisplayMoreInformationInToolTip ? GetFileMoreInfoTooltip(filePath) : filePath,
ContextData = new SearchResult { Type = ResultType.File, FullPath = filePath, WindowsIndexed = windowsIndexed }
};
return result;
@@ -347,41 +351,44 @@ namespace Flow.Launcher.Plugin.Explorer.Search
_ = Task.Run(() => EverythingApi.IncrementRunCounterAsync(fileOrFolder));
}
- private static string GetMoreInfoToolTip(string filePath, ResultType type)
+ private static string GetFileMoreInfoTooltip(string filePath)
{
- switch (type)
+ try
{
- case ResultType.Folder:
- try
- {
- var folderSize = PreviewPanel.GetFolderSize(filePath);
- var folderCreatedAt = PreviewPanel.GetFolderCreatedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
- var folderModifiedAt = PreviewPanel.GetFolderLastModifiedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
- return string.Format(Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info"),
- filePath, folderSize, folderCreatedAt, folderModifiedAt, Environment.NewLine);
- }
- catch (Exception e)
- {
- Context.API.LogException(ClassName, $"Failed to load tooltip for {filePath}", e);
- return filePath;
- }
- case ResultType.File:
- try
- {
- var fileSize = PreviewPanel.GetFileSize(filePath);
- var fileCreatedAt = PreviewPanel.GetFileCreatedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
- var fileModifiedAt = PreviewPanel.GetFileLastModifiedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
- return string.Format(Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info"),
- filePath, fileSize, fileCreatedAt, fileModifiedAt, Environment.NewLine);
- }
- catch (Exception e)
- {
- Context.API.LogException(ClassName, $"Failed to load tooltip for {filePath}", e);
- return filePath;
- }
- default:
- return filePath;
+ var fileSize = PreviewPanel.GetFileSize(filePath);
+ var fileCreatedAt = PreviewPanel.GetFileCreatedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
+ var fileModifiedAt = PreviewPanel.GetFileLastModifiedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
+ return string.Format(Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info"),
+ filePath, fileSize, fileCreatedAt, fileModifiedAt, Environment.NewLine);
}
+ catch (Exception e)
+ {
+ Context.API.LogException(ClassName, $"Failed to load tooltip for {filePath}", e);
+ return filePath;
+ }
+ }
+
+ private static string GetFolderMoreInfoTooltip(string folderPath)
+ {
+ try
+ {
+ var folderSize = PreviewPanel.GetFolderSize(folderPath);
+ var folderCreatedAt = PreviewPanel.GetFolderCreatedAt(folderPath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
+ var folderModifiedAt = PreviewPanel.GetFolderLastModifiedAt(folderPath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
+ return string.Format(Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info"),
+ folderPath, folderSize, folderCreatedAt, folderModifiedAt, Environment.NewLine);
+ }
+ catch (Exception e)
+ {
+ Context.API.LogException(ClassName, $"Failed to load tooltip for {folderPath}", e);
+ return folderPath;
+ }
+ }
+
+ private static string GetVolumeMoreInfoTooltip(string volumePath, string freespace, string totalspace)
+ {
+ return string.Format(Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_volume"),
+ volumePath, freespace, totalspace, Environment.NewLine);
}
private static readonly string[] MediaExtensions = { ".jpg", ".png", ".avi", ".mkv", ".bmp", ".gif", ".wmv", ".mp3", ".flac", ".mp4" };
From 5fcb166060c72d545708a20b14fc18d9930b4bb4 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 5 Jun 2025 16:12:55 +0800
Subject: [PATCH 1430/1697] Use PInvoke & Improve code comments & Use switch
sentences
---
.../NativeMethods.txt | 5 +
Flow.Launcher.Infrastructure/Win32Helper.cs | 5 +
Flow.Launcher/MainWindow.xaml.cs | 130 +++++++++---------
3 files changed, 74 insertions(+), 66 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/NativeMethods.txt b/Flow.Launcher.Infrastructure/NativeMethods.txt
index 53c877c4f..edc71feef 100644
--- a/Flow.Launcher.Infrastructure/NativeMethods.txt
+++ b/Flow.Launcher.Infrastructure/NativeMethods.txt
@@ -42,6 +42,11 @@ MONITORINFOEXW
WM_ENTERSIZEMOVE
WM_EXITSIZEMOVE
+WM_NCLBUTTONDBLCLK
+WM_SYSCOMMAND
+
+SC_MAXIMIZE
+SC_MINIMIZE
OleInitialize
OleUninitialize
diff --git a/Flow.Launcher.Infrastructure/Win32Helper.cs b/Flow.Launcher.Infrastructure/Win32Helper.cs
index 1be803fd4..86e7b7c97 100644
--- a/Flow.Launcher.Infrastructure/Win32Helper.cs
+++ b/Flow.Launcher.Infrastructure/Win32Helper.cs
@@ -324,6 +324,11 @@ namespace Flow.Launcher.Infrastructure
public const int WM_ENTERSIZEMOVE = (int)PInvoke.WM_ENTERSIZEMOVE;
public const int WM_EXITSIZEMOVE = (int)PInvoke.WM_EXITSIZEMOVE;
+ public const int WM_NCLBUTTONDBLCLK = (int)PInvoke.WM_NCLBUTTONDBLCLK;
+ public const int WM_SYSCOMMAND = (int)PInvoke.WM_SYSCOMMAND;
+
+ public const int SC_MAXIMIZE = (int)PInvoke.SC_MAXIMIZE;
+ public const int SC_MINIMIZE = (int)PInvoke.SC_MINIMIZE;
#endregion
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 13504fc93..a77d6471c 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -465,6 +465,9 @@ namespace Flow.Launcher
private void OnMouseDown(object sender, MouseButtonEventArgs e)
{
+ // When the window is maximized via Snap,
+ // dragging attempts will first switch the window from Maximized to Normal state,
+ // and adjust the drag position accordingly.
if (e.ChangedButton == MouseButton.Left)
{
try
@@ -472,8 +475,8 @@ namespace Flow.Launcher
if (WindowState == WindowState.Maximized)
{
// Calculate ratio based on maximized window dimensions
- double maxWidth = this.ActualWidth;
- double maxHeight = this.ActualHeight;
+ double maxWidth = ActualWidth;
+ double maxHeight = ActualHeight;
var mousePos = e.GetPosition(this);
double xRatio = mousePos.X / maxWidth;
double yRatio = mousePos.Y / maxHeight;
@@ -486,7 +489,7 @@ namespace Flow.Launcher
// Switch to Normal state
WindowState = WindowState.Normal;
- Dispatcher.BeginInvoke(new Action(() =>
+ Application.Current?.Dispatcher.Invoke(new Action(() =>
{
double normalWidth = Width;
double normalHeight = Height;
@@ -535,83 +538,78 @@ namespace Flow.Launcher
#region Window WndProc
- private const int WM_NCLBUTTONDBLCLK = 0x00A3;
- private const int WM_SYSCOMMAND = 0x0112;
- private const int SC_MAXIMIZE = 0xF030;
- private const int SC_RESTORE = 0xF120;
- private const int SC_MINIMIZE = 0xF020;
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
- {
- if (msg == Win32Helper.WM_ENTERSIZEMOVE)
- {
- _initialWidth = (int)Width;
- _initialHeight = (int)Height;
- handled = true;
- }
- else if (msg == Win32Helper.WM_EXITSIZEMOVE)
+ {
+ switch (msg)
{
- //Prevent updating the number of results when the window height is below the height of a single result item.
- //This situation occurs not only when the user manually resizes the window, but also when the window is released from a side snap, as the OS automatically adjusts the window height.
- //(Without this check, releasing from a snap can cause the window height to hit the minimum, resulting in only 2 results being shown.)
- if (_initialHeight != (int)Height && Height> (_settings.WindowHeightSize + _settings.ItemHeightSize))
- {
- if (!_settings.KeepMaxResults)
+ case Win32Helper.WM_ENTERSIZEMOVE:
+ _initialWidth = (int)Width;
+ _initialHeight = (int)Height;
+ handled = true;
+ break;
+ case Win32Helper.WM_EXITSIZEMOVE:
+ //Prevent updating the number of results when the window height is below the height of a single result item.
+ //This situation occurs not only when the user manually resizes the window, but also when the window is released from a side snap, as the OS automatically adjusts the window height.
+ //(Without this check, releasing from a snap can cause the window height to hit the minimum, resulting in only 2 results being shown.)
+ if (_initialHeight != (int)Height && Height > (_settings.WindowHeightSize + _settings.ItemHeightSize))
{
- // Get shadow margin
- var shadowMargin = 0;
- var (_, useDropShadowEffect) = _theme.GetActualValue();
- if (useDropShadowEffect)
+ if (!_settings.KeepMaxResults)
{
- shadowMargin = 32;
+ // 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;
+ }
+ else
+ {
+ _settings.MaxResultsToShow = Convert.ToInt32(Math.Truncate(itemCount));
+ }
}
- // Calculate max results to show
- var itemCount = (Height - (_settings.WindowHeightSize + 14) - shadowMargin) / _settings.ItemHeightSize;
- if (itemCount < 2)
- {
- _settings.MaxResultsToShow = 2;
- }
- else
- {
- _settings.MaxResultsToShow = Convert.ToInt32(Math.Truncate(itemCount));
- }
+ SizeToContent = SizeToContent.Height;
+ }
+ else
+ {
+ // Update height when exiting maximized snap state.
+ SizeToContent = SizeToContent.Height;
}
- SizeToContent = SizeToContent.Height;
- }
- else
- {
- // Update height when exiting maximized snap state.
- SizeToContent = SizeToContent.Height;
- }
-
- if (_initialWidth != (int)Width)
- {
- if (!_settings.KeepMaxResults)
+ if (_initialWidth != (int)Width)
{
- // Update width
- _viewModel.MainWindowWidth = Width;
+ if (!_settings.KeepMaxResults)
+ {
+ // Update width
+ _viewModel.MainWindowWidth = Width;
+ }
+
+ SizeToContent = SizeToContent.Height;
}
- SizeToContent = SizeToContent.Height;
- }
-
- handled = true;
- }
- if (msg == WM_NCLBUTTONDBLCLK)
- {
- SizeToContent = SizeToContent.Height;
- handled = true;
- }
- else if (msg == WM_SYSCOMMAND)
- {
- int command = wParam.ToInt32() & 0xFFF0;
- if (command == SC_MAXIMIZE || command == SC_MINIMIZE)
- {
+ handled = true;
+ break;
+ case Win32Helper.WM_NCLBUTTONDBLCLK: // Block the double click in frame
SizeToContent = SizeToContent.Height;
handled = true;
- }
+ break;
+ case Win32Helper.WM_SYSCOMMAND: // Block Maximize/Minimize by Win+Up and Win+Down Arrow
+ var command = wParam.ToInt32() & 0xFFF0;
+ if (command == Win32Helper.SC_MAXIMIZE || command == Win32Helper.SC_MINIMIZE)
+ {
+ SizeToContent = SizeToContent.Height;
+ handled = true;
+ }
+ break;
}
+
return IntPtr.Zero;
}
From 7d5001de1882dec8b678e9830fa64e95567b6118 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 5 Jun 2025 18:16:13 +0800
Subject: [PATCH 1431/1697] Catch exception when installing Everything
---
.../Languages/en.xaml | 3 ++
.../Everything/EverythingSearchManager.cs | 33 ++++++++++++++-----
2 files changed, 27 insertions(+), 9 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
index eefd6f4eb..9f60aaa43 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
@@ -162,6 +162,9 @@
Do you want to enable content search for Everything?
It can be very slow without index (which is only supported in Everything v1.5+)
+ Unable to find Everything.exe
+ Failed to install Everything, please install it manually
+
Native Context Menu
Display native context menu (experimental)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingSearchManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingSearchManager.cs
index 6c9155539..ce71c94ba 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingSearchManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingSearchManager.cs
@@ -11,6 +11,8 @@ namespace Flow.Launcher.Plugin.Explorer.Search.Everything
{
public class EverythingSearchManager : IIndexProvider, IContentIndexProvider, IPathIndexProvider
{
+ private static readonly string ClassName = nameof(EverythingSearchManager);
+
private Settings Settings { get; }
public EverythingSearchManager(Settings settings)
@@ -42,19 +44,32 @@ namespace Flow.Launcher.Plugin.Explorer.Search.Everything
private async ValueTask ClickToInstallEverythingAsync(ActionContext _)
{
- var installedPath = await EverythingDownloadHelper.PromptDownloadIfNotInstallAsync(Settings.EverythingInstalledPath, Main.Context.API);
-
- if (installedPath == null)
+ try
{
- Main.Context.API.ShowMsgError("Unable to find Everything.exe");
+ var installedPath = await EverythingDownloadHelper.PromptDownloadIfNotInstallAsync(Settings.EverythingInstalledPath, Main.Context.API);
+
+ if (installedPath == null)
+ {
+ Main.Context.API.ShowMsgError(Main.Context.API.GetTranslation("flowlauncher_plugin_everything_not_found"));
+ Main.Context.API.LogError(ClassName, "Unable to find Everything.exe");
+
+ return false;
+ }
+
+ Settings.EverythingInstalledPath = installedPath;
+ Process.Start(installedPath, "-startup");
+
+ return true;
+ }
+ // Sometimes Everything installation will fail because of permission issues or file not found issues
+ // Just let the user know that Everything is not installed properly and ask them to install it manually
+ catch (Exception e)
+ {
+ Main.Context.API.ShowMsgError(Main.Context.API.GetTranslation("flowlauncher_plugin_everything_install_issue"));
+ Main.Context.API.LogException(ClassName, "Failed to install Everything", e);
return false;
}
-
- Settings.EverythingInstalledPath = installedPath;
- Process.Start(installedPath, "-startup");
-
- return true;
}
public async IAsyncEnumerable SearchAsync(string search, [EnumeratorCancellation] CancellationToken token)
From b2e754dfd56c9dc40765e54c075b132f3ea930e9 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 5 Jun 2025 18:48:26 +0800
Subject: [PATCH 1432/1697] Fix command issue for pswh.exe
---
Plugins/Flow.Launcher.Plugin.Shell/Main.cs | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
index 2613c770b..2771a9118 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
@@ -242,6 +242,9 @@ namespace Flow.Launcher.Plugin.Shell
case Shell.Pwsh:
{
+ // Using just a ; doesn't work with wt, as it's used to create a new tab for the terminal window
+ // \\ must be escaped for it to work properly, or breaking it into multiple arguments
+ var addedCharacter = _settings.UseWindowsTerminal ? "\\" : "";
if (_settings.UseWindowsTerminal)
{
info.FileName = "wt.exe";
@@ -256,7 +259,7 @@ namespace Flow.Launcher.Plugin.Shell
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}{addedCharacter}; {(_settings.CloseShellAfterPress ? $"Write-Host '{Context.API.GetTranslation("flowlauncher_plugin_cmd_press_any_key_to_close")}'\\; [System.Console]::ReadKey()\\; exit" : "")}");
break;
}
From d7c7ec8f5ef0fd0ad7472b7df9d204da6784895f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 5 Jun 2025 18:55:58 +0800
Subject: [PATCH 1433/1697] Apply for all wt.exe
---
Plugins/Flow.Launcher.Plugin.Shell/Main.cs | 144 +++++++++++----------
1 file changed, 74 insertions(+), 70 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
index 2771a9118..d0add9f31 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
@@ -201,97 +201,101 @@ namespace Flow.Launcher.Plugin.Shell
switch (_settings.Shell)
{
case Shell.Cmd:
- {
- if (_settings.UseWindowsTerminal)
{
- info.FileName = "wt.exe";
- info.ArgumentList.Add("cmd");
- }
- else
- {
- info.FileName = "cmd.exe";
- }
+ 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;
- }
+ 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:
- {
- if (_settings.UseWindowsTerminal)
{
- info.FileName = "wt.exe";
- info.ArgumentList.Add("powershell");
+ // Using just a ; doesn't work with wt, as it's used to create a new tab for the terminal window
+ // \\ must be escaped for it to work properly, or breaking it into multiple arguments
+ var addedCharacter = _settings.UseWindowsTerminal ? "\\" : "";
+ if (_settings.UseWindowsTerminal)
+ {
+ info.FileName = "wt.exe";
+ info.ArgumentList.Add("powershell");
+ }
+ else
+ {
+ info.FileName = "powershell.exe";
+ }
+ if (_settings.LeaveShellOpen)
+ {
+ info.ArgumentList.Add("-NoExit");
+ info.ArgumentList.Add(command);
+ }
+ else
+ {
+ info.ArgumentList.Add("-Command");
+ info.ArgumentList.Add($"{command}{addedCharacter}; {(_settings.CloseShellAfterPress ? $"Write-Host '{Context.API.GetTranslation("flowlauncher_plugin_cmd_press_any_key_to_close")}'{addedCharacter}; [System.Console]::ReadKey(){addedCharacter}; exit" : "")}");
+ }
+ break;
}
- else
- {
- info.FileName = "powershell.exe";
- }
- if (_settings.LeaveShellOpen)
- {
- info.ArgumentList.Add("-NoExit");
- info.ArgumentList.Add(command);
- }
- 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" : "")}");
- }
- break;
- }
case Shell.Pwsh:
- {
- // Using just a ; doesn't work with wt, as it's used to create a new tab for the terminal window
- // \\ must be escaped for it to work properly, or breaking it into multiple arguments
- var addedCharacter = _settings.UseWindowsTerminal ? "\\" : "";
- if (_settings.UseWindowsTerminal)
{
- info.FileName = "wt.exe";
- info.ArgumentList.Add("pwsh");
+ // Using just a ; doesn't work with wt, as it's used to create a new tab for the terminal window
+ // \\ must be escaped for it to work properly, or breaking it into multiple arguments
+ var addedCharacter = _settings.UseWindowsTerminal ? "\\" : "";
+ 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}{addedCharacter}; {(_settings.CloseShellAfterPress ? $"Write-Host '{Context.API.GetTranslation("flowlauncher_plugin_cmd_press_any_key_to_close")}'{addedCharacter}; [System.Console]::ReadKey(){addedCharacter}; exit" : "")}");
+ break;
}
- else
- {
- info.FileName = "pwsh.exe";
- }
- if (_settings.LeaveShellOpen)
- {
- info.ArgumentList.Add("-NoExit");
- }
- info.ArgumentList.Add("-Command");
- info.ArgumentList.Add($"{command}{addedCharacter}; {(_settings.CloseShellAfterPress ? $"Write-Host '{Context.API.GetTranslation("flowlauncher_plugin_cmd_press_any_key_to_close")}'\\; [System.Console]::ReadKey()\\; exit" : "")}");
- break;
- }
case Shell.RunCommand:
- {
- var parts = command.Split(new[]
{
- ' '
- }, 2);
- if (parts.Length == 2)
- {
- var filename = parts[0];
- if (ExistInPath(filename))
+ var parts = command.Split(new[]
{
- var arguments = parts[1];
- info.FileName = filename;
- info.ArgumentList.Add(arguments);
+ ' '
+ }, 2);
+ if (parts.Length == 2)
+ {
+ var filename = parts[0];
+ if (ExistInPath(filename))
+ {
+ var arguments = parts[1];
+ info.FileName = filename;
+ info.ArgumentList.Add(arguments);
+ }
+ else
+ {
+ info.FileName = command;
+ }
}
else
{
info.FileName = command;
}
- }
- else
- {
- info.FileName = command;
+
+ info.UseShellExecute = true;
+
+ break;
}
- info.UseShellExecute = true;
-
- break;
- }
default:
throw new NotImplementedException();
}
From bf98a731b935e2e3aeaf03a25e6112f568a8b379 Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Thu, 5 Jun 2025 20:58:40 +1000
Subject: [PATCH 1434/1697] Update default plugin publish to follow production
version (#3656)
---
.github/workflows/default_plugins.yml | 85 ++++++---------------------
1 file changed, 17 insertions(+), 68 deletions(-)
diff --git a/.github/workflows/default_plugins.yml b/.github/workflows/default_plugins.yml
index 85acafae1..ec8dfcd4e 100644
--- a/.github/workflows/default_plugins.yml
+++ b/.github/workflows/default_plugins.yml
@@ -3,11 +3,10 @@ name: Publish Default Plugins
on:
push:
branches: ['master']
- paths: ['Plugins/**']
workflow_dispatch:
jobs:
- build:
+ publish:
runs-on: windows-latest
steps:
@@ -17,39 +16,24 @@ jobs:
with:
dotnet-version: 7.0.x
- - name: Determine New Plugin Updates
- uses: dorny/paths-filter@v3
- id: changes
- with:
- filters: |
- browserbookmark:
- - 'Plugins/Flow.Launcher.Plugin.BrowserBookmark/plugin.json'
- calculator:
- - 'Plugins/Flow.Launcher.Plugin.Calculator/plugin.json'
- explorer:
- - 'Plugins/Flow.Launcher.Plugin.Explorer/plugin.json'
- pluginindicator:
- - 'Plugins/Flow.Launcher.Plugin.PluginIndicator/plugin.json'
- pluginsmanager:
- - 'Plugins/Flow.Launcher.Plugin.PluginsManager/plugin.json'
- processkiller:
- - 'Plugins/Flow.Launcher.Plugin.ProcessKiller/plugin.json'
- program:
- - 'Plugins/Flow.Launcher.Plugin.Program/plugin.json'
- shell:
- - 'Plugins/Flow.Launcher.Plugin.Shell/plugin.json'
- sys:
- - 'Plugins/Flow.Launcher.Plugin.Sys/plugin.json'
- url:
- - 'Plugins/Flow.Launcher.Plugin.Url/plugin.json'
- websearch:
- - 'Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json'
- windowssettings:
- - 'Plugins/Flow.Launcher.Plugin.WindowsSettings/plugin.json'
- base: 'master'
+ - name: Update Plugins To Production Version
+ run: |
+ $version = "1.0.0"
+ Get-Content appveyor.yml | ForEach-Object {
+ if ($_ -match "version:\s*'(\d+\.\d+\.\d+)\.") {
+ $version = $matches[1]
+ }
+ }
+
+ $jsonFiles = Get-ChildItem -Path ".\Plugins\*\plugin.json"
+ foreach ($file in $jsonFiles) {
+ $plugin_old_ver = Get-Content $file.FullName -Raw | ConvertFrom-Json
+ (Get-Content $file) -replace '"Version"\s*:\s*".*?"', "`"Version`": `"$version`"" | Set-Content $file
+ $plugin_new_ver = Get-Content $file.FullName -Raw | ConvertFrom-Json
+ Write-Host "Updated" $plugin_old_ver.Name "version from" $plugin_old_ver.Version "to" $plugin_new_ver.Version
+ }
- name: Get BrowserBookmark Version
- if: steps.changes.outputs.browserbookmark == 'true'
id: updated-version-browserbookmark
uses: notiz-dev/github-action-json-property@release
with:
@@ -57,14 +41,12 @@ jobs:
prop_path: 'Version'
- name: Build BrowserBookmark
- if: steps.changes.outputs.browserbookmark == 'true'
run: |
dotnet publish 'Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj' --framework net7.0-windows -c Release -o "Flow.Launcher.Plugin.BrowserBookmark"
7z a -tzip "Flow.Launcher.Plugin.BrowserBookmark.zip" "./Flow.Launcher.Plugin.BrowserBookmark/*"
rm -r "Flow.Launcher.Plugin.BrowserBookmark"
- name: Publish BrowserBookmark
- if: steps.changes.outputs.browserbookmark == 'true'
uses: softprops/action-gh-release@v2
with:
repository: "Flow-Launcher/Flow.Launcher.Plugin.BrowserBookmark"
@@ -76,7 +58,6 @@ jobs:
- name: Get Calculator Version
- if: steps.changes.outputs.calculator == 'true'
id: updated-version-calculator
uses: notiz-dev/github-action-json-property@release
with:
@@ -84,14 +65,12 @@ jobs:
prop_path: 'Version'
- name: Build Calculator
- if: steps.changes.outputs.calculator == 'true'
run: |
dotnet publish 'Plugins/Flow.Launcher.Plugin.Calculator/Flow.Launcher.Plugin.Calculator.csproj' --framework net7.0-windows -c Release -o "Flow.Launcher.Plugin.Calculator"
7z a -tzip "Flow.Launcher.Plugin.Calculator.zip" "./Flow.Launcher.Plugin.Calculator/*"
rm -r "Flow.Launcher.Plugin.Calculator"
- name: Publish Calculator
- if: steps.changes.outputs.calculator == 'true'
uses: softprops/action-gh-release@v2
with:
repository: "Flow-Launcher/Flow.Launcher.Plugin.Calculator"
@@ -103,7 +82,6 @@ jobs:
- name: Get Explorer Version
- if: steps.changes.outputs.explorer == 'true'
id: updated-version-explorer
uses: notiz-dev/github-action-json-property@release
with:
@@ -111,14 +89,12 @@ jobs:
prop_path: 'Version'
- name: Build Explorer
- if: steps.changes.outputs.explorer == 'true'
run: |
dotnet publish 'Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj' --framework net7.0-windows -c Release -o "Flow.Launcher.Plugin.Explorer"
7z a -tzip "Flow.Launcher.Plugin.Explorer.zip" "./Flow.Launcher.Plugin.Explorer/*"
rm -r "Flow.Launcher.Plugin.Explorer"
- name: Publish Explorer
- if: steps.changes.outputs.explorer == 'true'
uses: softprops/action-gh-release@v2
with:
repository: "Flow-Launcher/Flow.Launcher.Plugin.Explorer"
@@ -130,7 +106,6 @@ jobs:
- name: Get PluginIndicator Version
- if: steps.changes.outputs.pluginindicator == 'true'
id: updated-version-pluginindicator
uses: notiz-dev/github-action-json-property@release
with:
@@ -138,14 +113,12 @@ jobs:
prop_path: 'Version'
- name: Build PluginIndicator
- if: steps.changes.outputs.pluginindicator == 'true'
run: |
dotnet publish 'Plugins/Flow.Launcher.Plugin.PluginIndicator/Flow.Launcher.Plugin.PluginIndicator.csproj' --framework net7.0-windows -c Release -o "Flow.Launcher.Plugin.PluginIndicator"
7z a -tzip "Flow.Launcher.Plugin.PluginIndicator.zip" "./Flow.Launcher.Plugin.PluginIndicator/*"
rm -r "Flow.Launcher.Plugin.PluginIndicator"
- name: Publish PluginIndicator
- if: steps.changes.outputs.pluginindicator == 'true'
uses: softprops/action-gh-release@v2
with:
repository: "Flow-Launcher/Flow.Launcher.Plugin.PluginIndicator"
@@ -157,7 +130,6 @@ jobs:
- name: Get PluginsManager Version
- if: steps.changes.outputs.pluginsmanager == 'true'
id: updated-version-pluginsmanager
uses: notiz-dev/github-action-json-property@release
with:
@@ -165,14 +137,12 @@ jobs:
prop_path: 'Version'
- name: Build PluginsManager
- if: steps.changes.outputs.pluginsmanager == 'true'
run: |
dotnet publish 'Plugins/Flow.Launcher.Plugin.PluginsManager/Flow.Launcher.Plugin.PluginsManager.csproj' --framework net7.0-windows -c Release -o "Flow.Launcher.Plugin.PluginsManager"
7z a -tzip "Flow.Launcher.Plugin.PluginsManager.zip" "./Flow.Launcher.Plugin.PluginsManager/*"
rm -r "Flow.Launcher.Plugin.PluginsManager"
- name: Publish PluginsManager
- if: steps.changes.outputs.pluginsmanager == 'true'
uses: softprops/action-gh-release@v2
with:
repository: "Flow-Launcher/Flow.Launcher.Plugin.PluginsManager"
@@ -184,7 +154,6 @@ jobs:
- name: Get ProcessKiller Version
- if: steps.changes.outputs.processkiller == 'true'
id: updated-version-processkiller
uses: notiz-dev/github-action-json-property@release
with:
@@ -192,14 +161,12 @@ jobs:
prop_path: 'Version'
- name: Build ProcessKiller
- if: steps.changes.outputs.processkiller == 'true'
run: |
dotnet publish 'Plugins/Flow.Launcher.Plugin.ProcessKiller/Flow.Launcher.Plugin.ProcessKiller.csproj' --framework net7.0-windows -c Release -o "Flow.Launcher.Plugin.ProcessKiller"
7z a -tzip "Flow.Launcher.Plugin.ProcessKiller.zip" "./Flow.Launcher.Plugin.ProcessKiller/*"
rm -r "Flow.Launcher.Plugin.ProcessKiller"
- name: Publish ProcessKiller
- if: steps.changes.outputs.processkiller == 'true'
uses: softprops/action-gh-release@v2
with:
repository: "Flow-Launcher/Flow.Launcher.Plugin.ProcessKiller"
@@ -211,7 +178,6 @@ jobs:
- name: Get Program Version
- if: steps.changes.outputs.program == 'true'
id: updated-version-program
uses: notiz-dev/github-action-json-property@release
with:
@@ -219,14 +185,12 @@ jobs:
prop_path: 'Version'
- name: Build Program
- if: steps.changes.outputs.program == 'true'
run: |
dotnet publish 'Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj' --framework net7.0-windows10.0.19041.0 -c Release -o "Flow.Launcher.Plugin.Program"
7z a -tzip "Flow.Launcher.Plugin.Program.zip" "./Flow.Launcher.Plugin.Program/*"
rm -r "Flow.Launcher.Plugin.Program"
- name: Publish Program
- if: steps.changes.outputs.program == 'true'
uses: softprops/action-gh-release@v2
with:
repository: "Flow-Launcher/Flow.Launcher.Plugin.Program"
@@ -238,7 +202,6 @@ jobs:
- name: Get Shell Version
- if: steps.changes.outputs.shell == 'true'
id: updated-version-shell
uses: notiz-dev/github-action-json-property@release
with:
@@ -246,14 +209,12 @@ jobs:
prop_path: 'Version'
- name: Build Shell
- if: steps.changes.outputs.shell == 'true'
run: |
dotnet publish 'Plugins/Flow.Launcher.Plugin.Shell/Flow.Launcher.Plugin.Shell.csproj' --framework net7.0-windows -c Release -o "Flow.Launcher.Plugin.Shell"
7z a -tzip "Flow.Launcher.Plugin.Shell.zip" "./Flow.Launcher.Plugin.Shell/*"
rm -r "Flow.Launcher.Plugin.Shell"
- name: Publish Shell
- if: steps.changes.outputs.shell == 'true'
uses: softprops/action-gh-release@v2
with:
repository: "Flow-Launcher/Flow.Launcher.Plugin.Shell"
@@ -265,7 +226,6 @@ jobs:
- name: Get Sys Version
- if: steps.changes.outputs.sys == 'true'
id: updated-version-sys
uses: notiz-dev/github-action-json-property@release
with:
@@ -273,14 +233,12 @@ jobs:
prop_path: 'Version'
- name: Build Sys
- if: steps.changes.outputs.sys == 'true'
run: |
dotnet publish 'Plugins/Flow.Launcher.Plugin.Sys/Flow.Launcher.Plugin.Sys.csproj' --framework net7.0-windows -c Release -o "Flow.Launcher.Plugin.Sys"
7z a -tzip "Flow.Launcher.Plugin.Sys.zip" "./Flow.Launcher.Plugin.Sys/*"
rm -r "Flow.Launcher.Plugin.Sys"
- name: Publish Sys
- if: steps.changes.outputs.sys == 'true'
uses: softprops/action-gh-release@v2
with:
repository: "Flow-Launcher/Flow.Launcher.Plugin.Sys"
@@ -292,7 +250,6 @@ jobs:
- name: Get Url Version
- if: steps.changes.outputs.url == 'true'
id: updated-version-url
uses: notiz-dev/github-action-json-property@release
with:
@@ -300,14 +257,12 @@ jobs:
prop_path: 'Version'
- name: Build Url
- if: steps.changes.outputs.url == 'true'
run: |
dotnet publish 'Plugins/Flow.Launcher.Plugin.Url/Flow.Launcher.Plugin.Url.csproj' --framework net7.0-windows -c Release -o "Flow.Launcher.Plugin.Url"
7z a -tzip "Flow.Launcher.Plugin.Url.zip" "./Flow.Launcher.Plugin.Url/*"
rm -r "Flow.Launcher.Plugin.Url"
- name: Publish Url
- if: steps.changes.outputs.url == 'true'
uses: softprops/action-gh-release@v2
with:
repository: "Flow-Launcher/Flow.Launcher.Plugin.Url"
@@ -319,7 +274,6 @@ jobs:
- name: Get WebSearch Version
- if: steps.changes.outputs.websearch == 'true'
id: updated-version-websearch
uses: notiz-dev/github-action-json-property@release
with:
@@ -327,14 +281,12 @@ jobs:
prop_path: 'Version'
- name: Build WebSearch
- if: steps.changes.outputs.websearch == 'true'
run: |
dotnet publish 'Plugins/Flow.Launcher.Plugin.WebSearch/Flow.Launcher.Plugin.WebSearch.csproj' --framework net7.0-windows -c Release -o "Flow.Launcher.Plugin.WebSearch"
7z a -tzip "Flow.Launcher.Plugin.WebSearch.zip" "./Flow.Launcher.Plugin.WebSearch/*"
rm -r "Flow.Launcher.Plugin.WebSearch"
- name: Publish WebSearch
- if: steps.changes.outputs.websearch == 'true'
uses: softprops/action-gh-release@v2
with:
repository: "Flow-Launcher/Flow.Launcher.Plugin.WebSearch"
@@ -346,7 +298,6 @@ jobs:
- name: Get WindowsSettings Version
- if: steps.changes.outputs.windowssettings == 'true'
id: updated-version-windowssettings
uses: notiz-dev/github-action-json-property@release
with:
@@ -354,14 +305,12 @@ jobs:
prop_path: 'Version'
- name: Build WindowsSettings
- if: steps.changes.outputs.windowssettings == 'true'
run: |
dotnet publish 'Plugins/Flow.Launcher.Plugin.WindowsSettings/Flow.Launcher.Plugin.WindowsSettings.csproj' --framework net7.0-windows -c Release -o "Flow.Launcher.Plugin.WindowsSettings"
7z a -tzip "Flow.Launcher.Plugin.WindowsSettings.zip" "./Flow.Launcher.Plugin.WindowsSettings/*"
rm -r "Flow.Launcher.Plugin.WindowsSettings"
- name: Publish WindowsSettings
- if: steps.changes.outputs.windowssettings == 'true'
uses: softprops/action-gh-release@v2
with:
repository: "Flow-Launcher/Flow.Launcher.Plugin.WindowsSettings"
From 08c8b8c09febcf1051dfc9e49f8f051b41bff646 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 5 Jun 2025 19:15:26 +0800
Subject: [PATCH 1435/1697] Do not show UI when shortcuts cannot be resolved
---
.../Programs/ShellLinkHelper.cs | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLinkHelper.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLinkHelper.cs
index a77b2ace8..34b3a6df2 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLinkHelper.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLinkHelper.cs
@@ -8,9 +8,8 @@ using Windows.Win32.Storage.FileSystem;
namespace Flow.Launcher.Plugin.Program.Programs
{
- class ShellLinkHelper
+ public class ShellLinkHelper
{
-
// Reference : http://www.pinvoke.net/default.aspx/Interfaces.IShellLinkW
[ComImport(), Guid("00021401-0000-0000-C000-000000000046")]
public class ShellLink
@@ -28,7 +27,9 @@ namespace Flow.Launcher.Plugin.Program.Programs
const int STGM_READ = 0;
((IPersistFile)link).Load(path, STGM_READ);
var hwnd = new HWND(IntPtr.Zero);
- ((IShellLinkW)link).Resolve(hwnd, 0);
+ // Use SLR_NO_UI to avoid showing any UI during resolution, like Problem with Shortcut dialogs
+ // https://learn.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-ishelllinka-resolve
+ ((IShellLinkW)link).Resolve(hwnd, (uint)SLR_FLAGS.SLR_NO_UI);
const int MAX_PATH = 260;
Span buffer = stackalloc char[MAX_PATH];
@@ -79,6 +80,6 @@ namespace Flow.Launcher.Plugin.Program.Programs
Marshal.ReleaseComObject(link);
return target;
- }
+ }
}
}
From a74a59914be014a297bb1077b8262262c1eec15d Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Thu, 5 Jun 2025 22:54:28 +1000
Subject: [PATCH 1436/1697] Add get PR authors to workflow (#3611)
---
.github/update_release_pr.py | 35 +++++++++++++++++++++++++++++++----
1 file changed, 31 insertions(+), 4 deletions(-)
diff --git a/.github/update_release_pr.py b/.github/update_release_pr.py
index f90f6181d..ccea511b3 100644
--- a/.github/update_release_pr.py
+++ b/.github/update_release_pr.py
@@ -11,7 +11,7 @@ def get_github_prs(token: str, owner: str, repo: str, label: str = "", state: st
token (str): GitHub token.
owner (str): The owner of the repository.
repo (str): The name of the repository.
- label (str): The label name.
+ label (str): The label name. Filter is not applied when empty string.
state (str): State of PR, e.g. open, closed, all
Returns:
@@ -89,7 +89,7 @@ def get_prs(pull_request_items: list[dict], label: str = "", state: str = "all")
Args:
pull_request_items (list[dict]): List of PR items.
- label (str): The label name.
+ label (str): The label name. Filter is not applied when empty string.
state (str): State of PR, e.g. open, closed, all
Returns:
@@ -99,14 +99,36 @@ def get_prs(pull_request_items: list[dict], label: str = "", state: str = "all")
pr_list = []
count = 0
for pr in pull_request_items:
- if pr["state"] == state and [item for item in pr["labels"] if item["name"] == label]:
+ if state in [pr["state"], "all"] and (not label or [item for item in pr["labels"] if item["name"] == label]):
pr_list.append(pr)
count += 1
- print(f"Found {count} PRs with {label if label else 'no'} label and state as {state}")
+ print(f"Found {count} PRs with {label if label else 'no filter on'} label and state as {state}")
return pr_list
+def get_prs_assignees(pull_request_items: list[dict], label: str = "", state: str = "all") -> list[str]:
+ """
+ Returns a list of pull request assignees after applying the label and state filters, excludes jjw24.
+
+ Args:
+ pull_request_items (list[dict]): List of PR items.
+ label (str): The label name. Filter is not applied when empty string.
+ state (str): State of PR, e.g. open, closed, all
+
+ Returns:
+ list: A list of strs, where each string is an assignee name. List is not distinct, so can contain
+ duplicate names.
+ Returns an empty list if none are found.
+ """
+ assignee_list = []
+ for pr in pull_request_items:
+ if state in [pr["state"], "all"] and (not label or [item for item in pr["labels"] if item["name"] == label]):
+ [assignee_list.append(assignee["login"]) for assignee in pr["assignees"] if assignee["login"] != "jjw24" ]
+
+ print(f"Found {len(assignee_list)} assignees with {label if label else 'no filter on'} label and state as {state}")
+
+ return assignee_list
def get_pr_descriptions(pull_request_items: list[dict]) -> str:
"""
@@ -208,6 +230,11 @@ if __name__ == "__main__":
description_content += f"## Features\n{get_pr_descriptions(enhancement_prs)}" if enhancement_prs else ""
description_content += f"## Bug fixes\n{get_pr_descriptions(bug_fix_prs)}" if bug_fix_prs else ""
+ assignees = list(set(get_prs_assignees(pull_requests, "enhancement", "closed") + get_prs_assignees(pull_requests, "bug", "closed")))
+ assignees.sort(key=str.lower)
+
+ description_content += f"### Authors:\n{', '.join(assignees)}"
+
update_pull_request_description(
github_token, repository_owner, repository_name, release_pr[0]["number"], description_content
)
From 1697544cb65b4d766c58f41fb2a27ef4b59c37e8 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 5 Jun 2025 22:41:21 +0800
Subject: [PATCH 1437/1697] Add example code comments
---
.../FirefoxBookmarkLoader.cs | 28 +++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
index 492a76c7b..f3b4c109f 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
@@ -270,6 +270,7 @@ public class FirefoxBookmarkLoader : FirefoxBookmarkLoaderBase
///
/// Path to places.sqlite
///
+ ///
private static string PlacesPath
{
get
@@ -295,6 +296,33 @@ public class FirefoxBookmarkLoader : FirefoxBookmarkLoaderBase
var indexOfDefaultProfileAttributePath = lines.IndexOf("Path=" + defaultProfileFolderName);
+ /*
+ Current profiles.ini structure example as of Firefox version 69.0.1
+
+ [Install736426B0AF4A39CB]
+ Default=Profiles/7789f565.default-release <== this is the default profile this plugin will get the bookmarks from. When opened Firefox will load the default profile
+ Locked=1
+
+ [Profile2]
+ Name=newblahprofile
+ IsRelative=0
+ Path=C:\t6h2yuq8.newblahprofile <== Note this is a custom location path for the profile user can set, we need to cater for this in code.
+
+ [Profile1]
+ Name=default
+ IsRelative=1
+ Path=Profiles/cydum7q4.default
+ Default=1
+
+ [Profile0]
+ Name=default-release
+ IsRelative=1
+ Path=Profiles/7789f565.default-release
+
+ [General]
+ StartWithLastProfile=1
+ Version=2
+ */
// Seen in the example above, the IsRelative attribute is always above the Path attribute
var relativeAttribute = lines[indexOfDefaultProfileAttributePath - 1];
From 79d35bba5f398562fcde4ffea6ac9f70fa5a9004 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 5 Jun 2025 22:54:34 +0800
Subject: [PATCH 1438/1697] Check index before returning PlacesPath
---
.../FirefoxBookmarkLoader.cs | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
index f3b4c109f..acace2506 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
@@ -324,11 +324,22 @@ public class FirefoxBookmarkLoader : FirefoxBookmarkLoaderBase
Version=2
*/
// Seen in the example above, the IsRelative attribute is always above the Path attribute
+
+ var relativePath = Path.Combine(defaultProfileFolderName, "places.sqlite");
+ var absoluePath = Path.Combine(profileFolderPath, relativePath);
+
+ // If the index is out of range, it means that the default profile is in a custom location or the file is malformed
+ // If the profile is in a custom location, we need to check
+ if (indexOfDefaultProfileAttributePath - 1 < 0 ||
+ indexOfDefaultProfileAttributePath - 1 >= lines.Count)
+ {
+ return Directory.Exists(absoluePath) ? absoluePath : relativePath;
+ }
+
var relativeAttribute = lines[indexOfDefaultProfileAttributePath - 1];
return relativeAttribute == "0" // See above, the profile is located in a custom location, path is not relative, so IsRelative=0
- ? defaultProfileFolderName + @"\places.sqlite"
- : Path.Combine(profileFolderPath, defaultProfileFolderName) + @"\places.sqlite";
+ ? relativePath : absoluePath;
}
}
}
From 71e224a131e3d59511269717c37b4d161579aaf9 Mon Sep 17 00:00:00 2001
From: Jack Ye <1160210343@qq.com>
Date: Thu, 5 Jun 2025 23:05:02 +0800
Subject: [PATCH 1439/1697] Add prerelease version checkbox for reporting
issues
---
.github/ISSUE_TEMPLATE/bug-report.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.github/ISSUE_TEMPLATE/bug-report.yaml b/.github/ISSUE_TEMPLATE/bug-report.yaml
index 294c06fc1..11a921955 100644
--- a/.github/ISSUE_TEMPLATE/bug-report.yaml
+++ b/.github/ISSUE_TEMPLATE/bug-report.yaml
@@ -16,6 +16,8 @@ body:
I have checked that this issue has not already been reported.
- label: >
I am using the latest version of Flow Launcher.
+ - label: >
+ I am using the prerelease version of Flow Launcher.
- type: textarea
attributes:
From abe287f47c606aa2c4616a35277a5fb8cc0e2a5f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 6 Jun 2025 09:33:34 +0800
Subject: [PATCH 1440/1697] Add MMM date format
---
.../ViewModels/SettingsViewModel.cs | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
index fb33dacab..680663e1e 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
@@ -243,6 +243,21 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
"yyyy-MM-dd",
"yyyy-MM-dd ddd",
"yyyy-MM-dd, dddd",
+ "dd/MMM/yyyy",
+ "dd/MMM/yyyy ddd",
+ "dd/MMM/yyyy, dddd",
+ "dd-MMM-yyyy",
+ "dd-MMM-yyyy ddd",
+ "dd-MMM-yyyy, dddd",
+ "dd.MMM.yyyy",
+ "dd.MMM.yyyy ddd",
+ "dd.MMM.yyyy, dddd",
+ "MMM/dd/yyyy",
+ "MMM/dd/yyyy ddd",
+ "MMM/dd/yyyy, dddd",
+ "yyyy-MMM-dd",
+ "yyyy-MMM-dd ddd",
+ "yyyy-MMM-dd, dddd",
};
#endregion
From 33a5ca845a5700e28c1d886cbf151aebdf6af791 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 6 Jun 2025 13:12:40 +0800
Subject: [PATCH 1441/1697] Support Msix FireFox bookmarks
---
.../FirefoxBookmarkLoader.cs | 165 +++++++++++-------
1 file changed, 98 insertions(+), 67 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
index acace2506..42a288e3a 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
@@ -264,84 +264,115 @@ public class FirefoxBookmarkLoader : FirefoxBookmarkLoaderBase
///
public override List GetBookmarks()
{
- return GetBookmarksFromPath(PlacesPath);
+ var bookmarks1 = GetBookmarksFromPath(PlacesPath);
+ var bookmarks2 = GetBookmarksFromPath(MsixPlacesPath);
+ return bookmarks1.Concat(bookmarks2).ToList();
}
///
- /// Path to places.sqlite
+ /// Path to places.sqlite of Msi installer
+ /// E.g. C:\Users\{UserName}\AppData\Roaming\Mozilla\Firefox
+ ///
///
- ///
private static string PlacesPath
{
get
{
var profileFolderPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"Mozilla\Firefox");
- var profileIni = Path.Combine(profileFolderPath, @"profiles.ini");
-
- if (!File.Exists(profileIni))
- return string.Empty;
-
- // get firefox default profile directory from profiles.ini
- using var sReader = new StreamReader(profileIni);
- var ini = sReader.ReadToEnd();
-
- var lines = ini.Split("\r\n").ToList();
-
- var defaultProfileFolderNameRaw = lines.FirstOrDefault(x => x.Contains("Default=") && x != "Default=1") ?? string.Empty;
-
- if (string.IsNullOrEmpty(defaultProfileFolderNameRaw))
- return string.Empty;
-
- var defaultProfileFolderName = defaultProfileFolderNameRaw.Split('=').Last();
-
- var indexOfDefaultProfileAttributePath = lines.IndexOf("Path=" + defaultProfileFolderName);
-
- /*
- Current profiles.ini structure example as of Firefox version 69.0.1
-
- [Install736426B0AF4A39CB]
- Default=Profiles/7789f565.default-release <== this is the default profile this plugin will get the bookmarks from. When opened Firefox will load the default profile
- Locked=1
-
- [Profile2]
- Name=newblahprofile
- IsRelative=0
- Path=C:\t6h2yuq8.newblahprofile <== Note this is a custom location path for the profile user can set, we need to cater for this in code.
-
- [Profile1]
- Name=default
- IsRelative=1
- Path=Profiles/cydum7q4.default
- Default=1
-
- [Profile0]
- Name=default-release
- IsRelative=1
- Path=Profiles/7789f565.default-release
-
- [General]
- StartWithLastProfile=1
- Version=2
- */
- // Seen in the example above, the IsRelative attribute is always above the Path attribute
-
- var relativePath = Path.Combine(defaultProfileFolderName, "places.sqlite");
- var absoluePath = Path.Combine(profileFolderPath, relativePath);
-
- // If the index is out of range, it means that the default profile is in a custom location or the file is malformed
- // If the profile is in a custom location, we need to check
- if (indexOfDefaultProfileAttributePath - 1 < 0 ||
- indexOfDefaultProfileAttributePath - 1 >= lines.Count)
- {
- return Directory.Exists(absoluePath) ? absoluePath : relativePath;
- }
-
- var relativeAttribute = lines[indexOfDefaultProfileAttributePath - 1];
-
- return relativeAttribute == "0" // See above, the profile is located in a custom location, path is not relative, so IsRelative=0
- ? relativePath : absoluePath;
+ return GetProfileIniPath(profileFolderPath);
}
}
+
+ ///
+ /// Path to places.sqlite of MSIX installer
+ /// E.g. C:\Users\{UserName}\AppData\Local\Packages\Mozilla.Firefox_n80bbvh6b1yt2\LocalCache\Roaming\Mozilla\Firefox
+ ///
+ ///
+ public static string MsixPlacesPath
+ {
+ get
+ {
+ var platformPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
+ var packagesPath = Path.Combine(platformPath, "Packages");
+
+ // Search for folder with Mozilla.Firefox prefix
+ var firefoxPackageFolder = Directory.EnumerateDirectories(packagesPath, "Mozilla.Firefox*",
+ SearchOption.TopDirectoryOnly).FirstOrDefault();
+
+ // Msix FireFox not installed
+ if (firefoxPackageFolder == null) return string.Empty;
+
+ var profileFolderPath = Path.Combine(firefoxPackageFolder, @"LocalCache\Roaming\Mozilla\Firefox");
+ return GetProfileIniPath(profileFolderPath);
+ }
+ }
+
+ private static string GetProfileIniPath(string profileFolderPath)
+ {
+ var profileIni = Path.Combine(profileFolderPath, @"profiles.ini");
+ if (!File.Exists(profileIni))
+ return string.Empty;
+
+ // get firefox default profile directory from profiles.ini
+ using var sReader = new StreamReader(profileIni);
+ var ini = sReader.ReadToEnd();
+
+ var lines = ini.Split("\r\n").ToList();
+
+ var defaultProfileFolderNameRaw = lines.FirstOrDefault(x => x.Contains("Default=") && x != "Default=1") ?? string.Empty;
+
+ if (string.IsNullOrEmpty(defaultProfileFolderNameRaw))
+ return string.Empty;
+
+ var defaultProfileFolderName = defaultProfileFolderNameRaw.Split('=').Last();
+
+ var indexOfDefaultProfileAttributePath = lines.IndexOf("Path=" + defaultProfileFolderName);
+
+ /*
+ Current profiles.ini structure example as of Firefox version 69.0.1
+
+ [Install736426B0AF4A39CB]
+ Default=Profiles/7789f565.default-release <== this is the default profile this plugin will get the bookmarks from. When opened Firefox will load the default profile
+ Locked=1
+
+ [Profile2]
+ Name=newblahprofile
+ IsRelative=0
+ Path=C:\t6h2yuq8.newblahprofile <== Note this is a custom location path for the profile user can set, we need to cater for this in code.
+
+ [Profile1]
+ Name=default
+ IsRelative=1
+ Path=Profiles/cydum7q4.default
+ Default=1
+
+ [Profile0]
+ Name=default-release
+ IsRelative=1
+ Path=Profiles/7789f565.default-release
+
+ [General]
+ StartWithLastProfile=1
+ Version=2
+ */
+ // Seen in the example above, the IsRelative attribute is always above the Path attribute
+
+ var relativePath = Path.Combine(defaultProfileFolderName, "places.sqlite");
+ var absoluePath = Path.Combine(profileFolderPath, relativePath);
+
+ // If the index is out of range, it means that the default profile is in a custom location or the file is malformed
+ // If the profile is in a custom location, we need to check
+ if (indexOfDefaultProfileAttributePath - 1 < 0 ||
+ indexOfDefaultProfileAttributePath - 1 >= lines.Count)
+ {
+ return Directory.Exists(absoluePath) ? absoluePath : relativePath;
+ }
+
+ var relativeAttribute = lines[indexOfDefaultProfileAttributePath - 1];
+
+ return relativeAttribute == "0" // See above, the profile is located in a custom location, path is not relative, so IsRelative=0
+ ? relativePath : absoluePath;
+ }
}
public static class Extensions
From 57470a9799d9e968932f1b4e37c194f19bf428ad Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 6 Jun 2025 13:21:51 +0800
Subject: [PATCH 1442/1697] Fix IsRelative logic.
---
.../FirefoxBookmarkLoader.cs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
index 42a288e3a..61fd05073 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
@@ -370,7 +370,8 @@ public class FirefoxBookmarkLoader : FirefoxBookmarkLoaderBase
var relativeAttribute = lines[indexOfDefaultProfileAttributePath - 1];
- return relativeAttribute == "0" // See above, the profile is located in a custom location, path is not relative, so IsRelative=0
+ // See above, the profile is located in a custom location, path is not relative, so IsRelative=0
+ return (relativeAttribute == "0" || relativeAttribute == "IsRelative=0")
? relativePath : absoluePath;
}
}
From f59e2399b9d0a58ea59eac2cdee87810a9fcb350 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 6 Jun 2025 13:25:43 +0800
Subject: [PATCH 1443/1697] Add error handling for directory operation
---
.../FirefoxBookmarkLoader.cs | 22 ++++++++++++-------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
index 61fd05073..ac382275f 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
@@ -294,16 +294,22 @@ public class FirefoxBookmarkLoader : FirefoxBookmarkLoaderBase
{
var platformPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
var packagesPath = Path.Combine(platformPath, "Packages");
-
- // Search for folder with Mozilla.Firefox prefix
- var firefoxPackageFolder = Directory.EnumerateDirectories(packagesPath, "Mozilla.Firefox*",
- SearchOption.TopDirectoryOnly).FirstOrDefault();
+ try
+ {
+ // Search for folder with Mozilla.Firefox prefix
+ var firefoxPackageFolder = Directory.EnumerateDirectories(packagesPath, "Mozilla.Firefox*",
+ SearchOption.TopDirectoryOnly).FirstOrDefault();
- // Msix FireFox not installed
- if (firefoxPackageFolder == null) return string.Empty;
+ // Msix FireFox not installed
+ if (firefoxPackageFolder == null) return string.Empty;
- var profileFolderPath = Path.Combine(firefoxPackageFolder, @"LocalCache\Roaming\Mozilla\Firefox");
- return GetProfileIniPath(profileFolderPath);
+ var profileFolderPath = Path.Combine(firefoxPackageFolder, @"LocalCache\Roaming\Mozilla\Firefox");
+ return GetProfileIniPath(profileFolderPath);
+ }
+ catch
+ {
+ return string.Empty;
+ }
}
}
From 8c5e0c948f6e1cc799b912207e8bbeb92967c776 Mon Sep 17 00:00:00 2001
From: DB P
Date: Fri, 6 Jun 2025 17:05:12 +0900
Subject: [PATCH 1444/1697] Change Tabcontrol to Expander
---
.../Views/ExplorerSettings.xaml | 1370 ++++++++---------
.../Views/ExplorerSettings.xaml.cs | 49 +-
2 files changed, 698 insertions(+), 721 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
index 4302e721a..eff1b4751 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
@@ -10,97 +10,13 @@
xmlns:ui="http://schemas.modernwpf.com/2019"
xmlns:viewModels="clr-namespace:Flow.Launcher.Plugin.Explorer.ViewModels"
xmlns:views="clr-namespace:Flow.Launcher.Plugin.Explorer.Views"
+ Margin="-72 0 -19 -14"
d:DataContext="{d:DesignInstance viewModels:SettingsViewModel}"
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d">
-
-
@@ -163,653 +79,685 @@
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
-
+ Content="{DynamicResource plugin_explorer_default_open_in_file_manager}"
+ IsChecked="{Binding Settings.DefaultOpenFolderInFileManager}" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+ Text="{DynamicResource plugin_explorer_Index_Search_Engine}" />
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ Orientation="Horizontal">
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
\ No newline at end of file
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml.cs
index 9203ece9a..0191e8a53 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml.cs
@@ -1,4 +1,5 @@
-using System.ComponentModel;
+using System.Collections.Generic;
+using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Windows;
@@ -11,28 +12,39 @@ using DragEventArgs = System.Windows.DragEventArgs;
namespace Flow.Launcher.Plugin.Explorer.Views
{
- ///
- /// Interaction logic for ExplorerSettings.xaml
- ///
public partial class ExplorerSettings
{
private readonly SettingsViewModel viewModel;
+ private List _expanders;
public ExplorerSettings(SettingsViewModel viewModel)
{
DataContext = viewModel;
-
InitializeComponent();
-
this.viewModel = viewModel;
-
- DataContext = viewModel;
+ // DataContext = viewModel; // Removed duplicate
ActionKeywordModel.Init(viewModel.Settings);
- lbxAccessLinks.Items.SortDescriptions.Add(new SortDescription("Path", ListSortDirection.Ascending));
+ // Ensure lbxAccessLinks and lbxExcludedPaths are initialized before accessing Items
+ // This might require Loaded event if they are not immediately available
+ // For now, assuming they are available after InitializeComponent()
+ if (lbxAccessLinks != null)
+ lbxAccessLinks.Items.SortDescriptions.Add(new SortDescription("Path", ListSortDirection.Ascending));
+
+ if (lbxExcludedPaths != null)
+ lbxExcludedPaths.Items.SortDescriptions.Add(new SortDescription("Path", ListSortDirection.Ascending));
- lbxExcludedPaths.Items.SortDescriptions.Add(new SortDescription("Path", ListSortDirection.Ascending));
+ _expanders = new List
+ {
+ GeneralSettingsExpander,
+ ContextMenuExpander,
+ PreviewPanelExpander,
+ EverythingExpander,
+ ActionKeywordsExpander,
+ QuickAccessExpander,
+ ExcludedPathsExpander
+ };
}
private void AccessLinkDragDrop(string containerName, DragEventArgs e)
@@ -93,5 +105,22 @@ namespace Flow.Launcher.Plugin.Explorer.Views
{
e.Handled = e.Text.ToCharArray().Any(c => !char.IsDigit(c));
}
+
+ private void Expander_Expanded(object sender, RoutedEventArgs e)
+ {
+ if (sender is Expander expandedExpander)
+ {
+ // Ensure _expanders is not null and contains items
+ if (_expanders == null || !_expanders.Any()) return;
+
+ foreach (var expander in _expanders)
+ {
+ if (expander != null && expander != expandedExpander && expander.IsExpanded)
+ {
+ expander.IsExpanded = false;
+ }
+ }
+ }
+ }
}
}
From 6cd830c5b5088f30364607a1b6489ea468e9570e Mon Sep 17 00:00:00 2001
From: DB P
Date: Fri, 6 Jun 2025 17:07:57 +0900
Subject: [PATCH 1445/1697] Fix Font Color
---
.../Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
index eff1b4751..ca395fc5e 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
@@ -88,6 +88,7 @@
From c2eca7dc39407212d1fbd1de03a11f475ffc0a59 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 6 Jun 2025 16:15:26 +0800
Subject: [PATCH 1446/1697] Improve code quality
---
.../Views/ExplorerSettings.xaml.cs | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml.cs
index 0191e8a53..bb52612e4 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml.cs
@@ -14,15 +14,17 @@ namespace Flow.Launcher.Plugin.Explorer.Views
{
public partial class ExplorerSettings
{
- private readonly SettingsViewModel viewModel;
- private List _expanders;
+ private readonly SettingsViewModel _viewModel;
+ private readonly List _expanders;
public ExplorerSettings(SettingsViewModel viewModel)
{
+ _viewModel = viewModel;
DataContext = viewModel;
+
InitializeComponent();
- this.viewModel = viewModel;
- // DataContext = viewModel; // Removed duplicate
+
+ DataContext = viewModel;
ActionKeywordModel.Init(viewModel.Settings);
@@ -63,7 +65,7 @@ namespace Flow.Launcher.Plugin.Explorer.Views
{
Path = s
};
- viewModel.AppendLink(containerName, newFolderLink);
+ _viewModel.AppendLink(containerName, newFolderLink);
}
}
}
@@ -88,8 +90,8 @@ namespace Flow.Launcher.Plugin.Explorer.Views
{
if (tbFastSortWarning is not null)
{
- tbFastSortWarning.Visibility = viewModel.FastSortWarningVisibility;
- tbFastSortWarning.Text = viewModel.SortOptionWarningMessage;
+ tbFastSortWarning.Visibility = _viewModel.FastSortWarningVisibility;
+ tbFastSortWarning.Text = _viewModel.SortOptionWarningMessage;
}
}
private void LbxAccessLinks_OnDrop(object sender, DragEventArgs e)
From 05cd01d1d61c2cb9b8ddcbb35a3590f584a02d4e Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 6 Jun 2025 16:20:43 +0800
Subject: [PATCH 1447/1697] Use loaded event to ensure accessability
---
.../Views/ExplorerSettings.xaml | 7 ++-
.../Views/ExplorerSettings.xaml.cs | 47 ++++++++++---------
2 files changed, 32 insertions(+), 22 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
index ca395fc5e..451d7afb2 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
@@ -110,6 +110,7 @@
Expanded="Expander_Expanded"
Header="{DynamicResource plugin_explorer_generalsetting_header}"
IsExpanded="False"
+ Loaded="GeneralSettingsExpander_Loaded"
Style="{StaticResource CustomExpanderStyle}">
@@ -664,6 +665,7 @@
Drop="LbxAccessLinks_OnDrop"
ItemTemplate="{StaticResource ListViewTemplateAccessLinks}"
ItemsSource="{Binding Settings.QuickAccessLinks}"
+ Loaded="lbxAccessLinks_Loaded"
SelectedItem="{Binding SelectedQuickAccessLink}" />
@@ -698,9 +700,11 @@
@@ -728,6 +732,7 @@
Drop="LbxExcludedPaths_OnDrop"
ItemTemplate="{StaticResource ListViewTemplateAccessLinks}"
ItemsSource="{Binding Settings.IndexSearchExcludedSubdirectoryPaths}"
+ Loaded="lbxExcludedPaths_Loaded"
SelectedItem="{Binding SelectedIndexSearchExcludedPath}" />
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml.cs
index bb52612e4..e82c10ae2 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml.cs
@@ -15,7 +15,7 @@ namespace Flow.Launcher.Plugin.Explorer.Views
public partial class ExplorerSettings
{
private readonly SettingsViewModel _viewModel;
- private readonly List _expanders;
+ private readonly List _expanders = new();
public ExplorerSettings(SettingsViewModel viewModel)
{
@@ -27,26 +27,6 @@ namespace Flow.Launcher.Plugin.Explorer.Views
DataContext = viewModel;
ActionKeywordModel.Init(viewModel.Settings);
-
- // Ensure lbxAccessLinks and lbxExcludedPaths are initialized before accessing Items
- // This might require Loaded event if they are not immediately available
- // For now, assuming they are available after InitializeComponent()
- if (lbxAccessLinks != null)
- lbxAccessLinks.Items.SortDescriptions.Add(new SortDescription("Path", ListSortDirection.Ascending));
-
- if (lbxExcludedPaths != null)
- lbxExcludedPaths.Items.SortDescriptions.Add(new SortDescription("Path", ListSortDirection.Ascending));
-
- _expanders = new List
- {
- GeneralSettingsExpander,
- ContextMenuExpander,
- PreviewPanelExpander,
- EverythingExpander,
- ActionKeywordsExpander,
- QuickAccessExpander,
- ExcludedPathsExpander
- };
}
private void AccessLinkDragDrop(string containerName, DragEventArgs e)
@@ -124,5 +104,30 @@ namespace Flow.Launcher.Plugin.Explorer.Views
}
}
}
+
+ private void lbxAccessLinks_Loaded(object sender, RoutedEventArgs e)
+ {
+ lbxAccessLinks.Items.SortDescriptions.Add(new SortDescription("Path", ListSortDirection.Ascending));
+ }
+
+ private void lbxExcludedPaths_Loaded(object sender, RoutedEventArgs e)
+ {
+ lbxExcludedPaths.Items.SortDescriptions.Add(new SortDescription("Path", ListSortDirection.Ascending));
+ }
+
+ private void GeneralSettingsExpander_Loaded(object sender, RoutedEventArgs e)
+ {
+ var expanders = new List
+ {
+ GeneralSettingsExpander,
+ ContextMenuExpander,
+ PreviewPanelExpander,
+ EverythingExpander,
+ ActionKeywordsExpander,
+ QuickAccessExpander,
+ ExcludedPathsExpander
+ };
+ _expanders.AddRange(expanders);
+ }
}
}
From b29bc75dcb8e4e50de3b48a7aff9716f5ca7f6b6 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 6 Jun 2025 16:53:31 +0800
Subject: [PATCH 1448/1697] Improve setting panel design
---
.../Views/ExplorerSettings.xaml | 23 ++++++++++---------
1 file changed, 12 insertions(+), 11 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
index 451d7afb2..83ef42688 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
@@ -10,7 +10,6 @@
xmlns:ui="http://schemas.modernwpf.com/2019"
xmlns:viewModels="clr-namespace:Flow.Launcher.Plugin.Explorer.ViewModels"
xmlns:views="clr-namespace:Flow.Launcher.Plugin.Explorer.Views"
- Margin="-72 0 -19 -14"
d:DataContext="{d:DesignInstance viewModels:SettingsViewModel}"
d:DesignHeight="450"
d:DesignWidth="800"
@@ -86,7 +85,7 @@
@@ -101,8 +100,9 @@
-
-
+
+
+
-
+
+
@@ -333,7 +334,7 @@
Header="{DynamicResource plugin_explorer_native_context_menu_header}"
IsExpanded="False"
Style="{StaticResource CustomExpanderStyle}">
-
+
@@ -403,7 +404,7 @@
Header="{DynamicResource plugin_explorer_previewpanel_setting_header}"
IsExpanded="False"
Style="{StaticResource CustomExpanderStyle}">
-
+
@@ -500,7 +501,7 @@
Header="{DynamicResource plugin_explorer_everything_setting_header}"
IsExpanded="False"
Style="{StaticResource CustomExpanderStyle}">
-
+
@@ -592,7 +593,7 @@
Header="{DynamicResource plugin_explorer_manageactionkeywords_header}"
IsExpanded="False"
Style="{StaticResource CustomExpanderStyle}">
-
+
@@ -638,7 +639,7 @@
Header="{DynamicResource plugin_explorer_quickaccesslinks_header}"
IsExpanded="False"
Style="{StaticResource CustomExpanderStyle}">
-
+
@@ -706,7 +707,7 @@
Header="{DynamicResource plugin_explorer_indexsearchexcludedpaths_header}"
IsExpanded="False"
Style="{StaticResource CustomExpanderStyle}">
-
+
From 569cb8bd44b743c104ec82dc6598ec8bbad42051 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 6 Jun 2025 16:57:48 +0800
Subject: [PATCH 1449/1697] Remove grid & scroll viewer & Remove bottom margin
---
.../Views/ExplorerSettings.xaml | 1290 ++++++++---------
1 file changed, 643 insertions(+), 647 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
index 83ef42688..070820a0d 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
@@ -101,670 +101,666 @@
-
-
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+ Margin="{StaticResource SettingPanelItemLeftTopBottomMargin}"
+ Content="{DynamicResource plugin_explorer_previewpanel_display_file_size_checkbox}"
+ IsChecked="{Binding ShowFileSizeInPreviewPanel}" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ Content="{DynamicResource plugin_explorer_previewpanel_display_file_creation_checkbox}"
+ IsChecked="{Binding ShowCreatedDateInPreviewPanel}" />
+ Margin="{StaticResource SettingPanelItemLeftTopBottomMargin}"
+ Content="{DynamicResource plugin_explorer_previewpanel_display_file_modification_checkbox}"
+ IsChecked="{Binding ShowModifiedDateInPreviewPanel}" />
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+ Text="{Binding PreviewPanelDateFormatDemo}" />
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ Text="{Binding PreviewPanelTimeFormatDemo}" />
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
From 6614771c3dfafd8a32d4573303f8ff479eea9477 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 6 Jun 2025 17:03:20 +0800
Subject: [PATCH 1450/1697] Move initialization to constructor
---
.../Views/ExplorerSettings.xaml | 1 -
.../Views/ExplorerSettings.xaml.cs | 28 ++++++++-----------
2 files changed, 12 insertions(+), 17 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
index 070820a0d..b81c3cac3 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
@@ -108,7 +108,6 @@
Expanded="Expander_Expanded"
Header="{DynamicResource plugin_explorer_generalsetting_header}"
IsExpanded="False"
- Loaded="GeneralSettingsExpander_Loaded"
Style="{StaticResource CustomExpanderStyle}">
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml.cs
index e82c10ae2..2c50f1c6f 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml.cs
@@ -15,7 +15,7 @@ namespace Flow.Launcher.Plugin.Explorer.Views
public partial class ExplorerSettings
{
private readonly SettingsViewModel _viewModel;
- private readonly List _expanders = new();
+ private readonly List _expanders;
public ExplorerSettings(SettingsViewModel viewModel)
{
@@ -27,6 +27,17 @@ namespace Flow.Launcher.Plugin.Explorer.Views
DataContext = viewModel;
ActionKeywordModel.Init(viewModel.Settings);
+
+ _expanders = new List
+ {
+ GeneralSettingsExpander,
+ ContextMenuExpander,
+ PreviewPanelExpander,
+ EverythingExpander,
+ ActionKeywordsExpander,
+ QuickAccessExpander,
+ ExcludedPathsExpander
+ };
}
private void AccessLinkDragDrop(string containerName, DragEventArgs e)
@@ -114,20 +125,5 @@ namespace Flow.Launcher.Plugin.Explorer.Views
{
lbxExcludedPaths.Items.SortDescriptions.Add(new SortDescription("Path", ListSortDirection.Ascending));
}
-
- private void GeneralSettingsExpander_Loaded(object sender, RoutedEventArgs e)
- {
- var expanders = new List
- {
- GeneralSettingsExpander,
- ContextMenuExpander,
- PreviewPanelExpander,
- EverythingExpander,
- ActionKeywordsExpander,
- QuickAccessExpander,
- ExcludedPathsExpander
- };
- _expanders.AddRange(expanders);
- }
}
}
From baef9ddacd119e5fdce544b8f5ee476482732408 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 6 Jun 2025 18:37:17 +0800
Subject: [PATCH 1451/1697] Expose ISaveable interface in derived class to make
sure we are calling the new version of Save method
---
.../Storage/FlowLauncherJsonStorage.cs | 4 +++-
Flow.Launcher.Infrastructure/Storage/PluginBinaryStorage.cs | 4 +++-
Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs | 4 +++-
3 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Storage/FlowLauncherJsonStorage.cs b/Flow.Launcher.Infrastructure/Storage/FlowLauncherJsonStorage.cs
index 158e0cdf5..857490bad 100644
--- a/Flow.Launcher.Infrastructure/Storage/FlowLauncherJsonStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/FlowLauncherJsonStorage.cs
@@ -2,11 +2,13 @@
using System.Threading.Tasks;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
+using Flow.Launcher.Plugin;
using Flow.Launcher.Plugin.SharedCommands;
namespace Flow.Launcher.Infrastructure.Storage
{
- public class FlowLauncherJsonStorage : JsonStorage where T : new()
+ // Expose ISaveable interface in derived class to make sure we are calling the new version of Save method
+ public class FlowLauncherJsonStorage : JsonStorage, ISavable where T : new()
{
private static readonly string ClassName = "FlowLauncherJsonStorage";
diff --git a/Flow.Launcher.Infrastructure/Storage/PluginBinaryStorage.cs b/Flow.Launcher.Infrastructure/Storage/PluginBinaryStorage.cs
index 01da96d62..0e0906e73 100644
--- a/Flow.Launcher.Infrastructure/Storage/PluginBinaryStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/PluginBinaryStorage.cs
@@ -1,11 +1,13 @@
using System.IO;
using System.Threading.Tasks;
using Flow.Launcher.Infrastructure.Logger;
+using Flow.Launcher.Plugin;
using Flow.Launcher.Plugin.SharedCommands;
namespace Flow.Launcher.Infrastructure.Storage
{
- public class PluginBinaryStorage : BinaryStorage where T : new()
+ // Expose ISaveable interface in derived class to make sure we are calling the new version of Save method
+ public class PluginBinaryStorage : BinaryStorage, ISavable where T : new()
{
private static readonly string ClassName = "PluginBinaryStorage";
diff --git a/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs b/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs
index 147152949..d59083071 100644
--- a/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs
@@ -2,11 +2,13 @@
using System.Threading.Tasks;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
+using Flow.Launcher.Plugin;
using Flow.Launcher.Plugin.SharedCommands;
namespace Flow.Launcher.Infrastructure.Storage
{
- public class PluginJsonStorage : JsonStorage where T : new()
+ // Expose ISaveable interface in derived class to make sure we are calling the new version of Save method
+ public class PluginJsonStorage : JsonStorage, ISavable where T : new()
{
// Use assembly name to check which plugin is using this storage
public readonly string AssemblyName;
From 062cd2ad1dc8dd8327a6a2cebdbd58e478c362d9 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 6 Jun 2025 18:38:05 +0800
Subject: [PATCH 1452/1697] Use ISavable instead of object
---
Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs | 2 +-
Flow.Launcher/PublicAPIInstance.cs | 10 ++++------
2 files changed, 5 insertions(+), 7 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
index 003e72a5d..435d97ab7 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
@@ -12,7 +12,7 @@ using Flow.Launcher.Plugin;
namespace Flow.Launcher.Core.Plugin
{
- public class JsonRPCPluginSettings
+ public class JsonRPCPluginSettings : ISavable
{
public required JsonRpcConfigurationModel? Configuration { get; init; }
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 80d5de53d..06e17baf0 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -276,7 +276,7 @@ namespace Flow.Launcher
public void LogException(string className, string message, Exception e, [CallerMemberName] string methodName = "") =>
Log.Exception(className, message, e, methodName);
- private readonly ConcurrentDictionary _pluginJsonStorages = new();
+ private readonly ConcurrentDictionary _pluginJsonStorages = new();
public void RemovePluginSettings(string assemblyName)
{
@@ -294,9 +294,8 @@ namespace Flow.Launcher
public void SavePluginSettings()
{
- foreach (var value in _pluginJsonStorages.Values)
+ foreach (var savable in _pluginJsonStorages.Values)
{
- var savable = value as ISavable;
savable?.Save();
}
}
@@ -496,7 +495,7 @@ namespace Flow.Launcher
public bool SetCurrentTheme(ThemeData theme) =>
Theme.ChangeTheme(theme.FileNameWithoutExtension);
- private readonly ConcurrentDictionary<(string, string, Type), object> _pluginBinaryStorages = new();
+ private readonly ConcurrentDictionary<(string, string, Type), ISavable> _pluginBinaryStorages = new();
public void RemovePluginCaches(string cacheDirectory)
{
@@ -513,9 +512,8 @@ namespace Flow.Launcher
public void SavePluginCaches()
{
- foreach (var value in _pluginBinaryStorages.Values)
+ foreach (var savable in _pluginBinaryStorages.Values)
{
- var savable = value as ISavable;
savable?.Save();
}
}
From 0c474a979ff48988b7624035c5b97047201e0312 Mon Sep 17 00:00:00 2001
From: DB P
Date: Fri, 6 Jun 2025 20:36:30 +0900
Subject: [PATCH 1453/1697] Add Hover Style / Adjust Arrow / Adjust Padding
---
.../Resources/CustomControlTemplate.xaml | 73 +++++++++++++
.../Views/ExplorerSettings.xaml | 101 +++++++++++++++---
2 files changed, 160 insertions(+), 14 deletions(-)
diff --git a/Flow.Launcher/Resources/CustomControlTemplate.xaml b/Flow.Launcher/Resources/CustomControlTemplate.xaml
index 08b239c41..cdaadd45a 100644
--- a/Flow.Launcher/Resources/CustomControlTemplate.xaml
+++ b/Flow.Launcher/Resources/CustomControlTemplate.xaml
@@ -2407,6 +2407,79 @@
+
+
+
+
From dc3fada88f642800dee716e223a61c1df4cd3eaf Mon Sep 17 00:00:00 2001
From: DB P
Date: Fri, 6 Jun 2025 20:38:07 +0900
Subject: [PATCH 1454/1697] Fix Border
---
.../Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
index 0d4710e24..05135e0d2 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
@@ -86,7 +86,7 @@
-
+
From 600137c91196c39b96c4881880aef744c3011e5a Mon Sep 17 00:00:00 2001
From: DB P
Date: Fri, 6 Jun 2025 20:38:37 +0900
Subject: [PATCH 1455/1697] Fix Border
---
.../Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
index 05135e0d2..47d53d463 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
@@ -86,7 +86,7 @@
-
+
From 82f3e99f0eec30c493169c1cf754ab80b88f7f8a Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 6 Jun 2025 20:08:11 +0800
Subject: [PATCH 1456/1697] Revert changes in ExplorerSettings.xaml
---
.../Views/ExplorerSettings.xaml | 44 +++++++------------
1 file changed, 17 insertions(+), 27 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
index 50151d0b0..b5ac95c44 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
@@ -198,7 +198,6 @@
-
@@ -223,17 +222,8 @@
Content="{DynamicResource plugin_explorer_default_open_in_file_manager}"
IsChecked="{Binding Settings.DefaultOpenFolderInFileManager}" />
-
-
@@ -260,7 +250,7 @@
@@ -287,7 +277,7 @@
@@ -314,14 +304,14 @@
Date: Fri, 6 Jun 2025 20:09:47 +0800
Subject: [PATCH 1457/1697] Add blank line back
---
.../Views/ExplorerSettings.xaml | 99 ++++++++++---------
1 file changed, 55 insertions(+), 44 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
index 331b238ca..ae9e25ad2 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
@@ -92,41 +92,43 @@
+ Background="{TemplateBinding Background}"
+ BorderBrush="{TemplateBinding BorderBrush}"
+ BorderThickness="{TemplateBinding BorderThickness}"
+ SnapsToDevicePixels="true">
-
+ x:Name="HeaderSite"
+ MinWidth="0"
+ MinHeight="0"
+ Margin="0"
+ Padding="{TemplateBinding Padding}"
+ HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
+ VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
+ Content="{TemplateBinding Header}"
+ ContentTemplate="{TemplateBinding HeaderTemplate}"
+ ContentTemplateSelector="{TemplateBinding HeaderTemplateSelector}"
+ DockPanel.Dock="Top"
+ FocusVisualStyle="{StaticResource ExpanderHeaderFocusVisual}"
+ FontFamily="{TemplateBinding FontFamily}"
+ FontSize="{TemplateBinding FontSize}"
+ FontStretch="{TemplateBinding FontStretch}"
+ FontStyle="{TemplateBinding FontStyle}"
+ FontWeight="{TemplateBinding FontWeight}"
+ Foreground="{TemplateBinding Foreground}"
+ IsChecked="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
+ Style="{StaticResource ExpanderHeaderRightArrowStyle}" />
+
+ x:Name="ExpandSite"
+ Margin="{TemplateBinding Padding}"
+ HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
+ VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
+ DockPanel.Dock="Bottom"
+ Focusable="false" />
@@ -141,13 +143,17 @@
+ Storyboard.TargetName="ContentPresenterBorder"
+ Storyboard.TargetProperty="(Border.LayoutTransform).(ScaleTransform.ScaleY)"
+ From="0.0"
+ To="1.0"
+ Duration="0:0:0" />
+ Storyboard.TargetName="ContentPresenterBorder"
+ Storyboard.TargetProperty="(Border.Opacity)"
+ From="0.0"
+ To="1.0"
+ Duration="0:0:0" />
@@ -155,13 +161,17 @@
+ Storyboard.TargetName="ContentPresenterBorder"
+ Storyboard.TargetProperty="(Border.LayoutTransform).(ScaleTransform.ScaleY)"
+ From="1.0"
+ To="0.0"
+ Duration="0:0:0" />
+ Storyboard.TargetName="ContentPresenterBorder"
+ Storyboard.TargetProperty="(Border.Opacity)"
+ From="1.0"
+ To="0.0"
+ Duration="0:0:0" />
@@ -367,6 +377,7 @@
HorizontalAlignment="Left"
Text="{Binding ExcludedFileTypes}"
ToolTip="{DynamicResource plugin_explorer_Excluded_File_Types_Tooltip}" />
+
Date: Fri, 6 Jun 2025 20:14:33 +0800
Subject: [PATCH 1458/1697] Add setting ui back
---
.../Views/ExplorerSettings.xaml | 44 ++++++++++++-------
1 file changed, 27 insertions(+), 17 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
index ae9e25ad2..93012bd36 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
@@ -207,6 +207,7 @@
+
@@ -230,16 +231,25 @@
Content="{DynamicResource plugin_explorer_default_open_in_file_manager}"
IsChecked="{Binding Settings.DefaultOpenFolderInFileManager}" />
-
+
+
@@ -258,7 +268,7 @@
@@ -285,7 +295,7 @@
@@ -312,14 +322,14 @@
Date: Fri, 6 Jun 2025 23:07:01 +0800
Subject: [PATCH 1459/1697] Add GetString api function
---
Flow.Launcher.Infrastructure/Http/Http.cs | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/Flow.Launcher.Infrastructure/Http/Http.cs b/Flow.Launcher.Infrastructure/Http/Http.cs
index a29f8accf..22eb065f5 100644
--- a/Flow.Launcher.Infrastructure/Http/Http.cs
+++ b/Flow.Launcher.Infrastructure/Http/Http.cs
@@ -220,5 +220,18 @@ namespace Flow.Launcher.Infrastructure.Http
return new HttpResponseMessage(HttpStatusCode.InternalServerError);
}
}
+
+ public static async Task GetStringAsync(string url, CancellationToken token = default)
+ {
+ try
+ {
+ Log.Debug(ClassName, $"Url <{url}>");
+ return await client.GetStringAsync(url, token);
+ }
+ catch (System.Exception e)
+ {
+ return string.Empty;
+ }
+ }
}
}
From 1f4578c04ce64325a1ad0fd8b20548fc039239cc Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 6 Jun 2025 23:08:32 +0800
Subject: [PATCH 1460/1697] Add release notes window
---
Flow.Launcher/Flow.Launcher.csproj | 1 +
Flow.Launcher/ReleaseNotesWindow.xaml | 168 +++++++++++++++++++++++
Flow.Launcher/ReleaseNotesWindow.xaml.cs | 149 ++++++++++++++++++++
3 files changed, 318 insertions(+)
create mode 100644 Flow.Launcher/ReleaseNotesWindow.xaml
create mode 100644 Flow.Launcher/ReleaseNotesWindow.xaml.cs
diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj
index 8d43eff98..4580798b2 100644
--- a/Flow.Launcher/Flow.Launcher.csproj
+++ b/Flow.Launcher/Flow.Launcher.csproj
@@ -90,6 +90,7 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/Flow.Launcher/ReleaseNotesWindow.xaml b/Flow.Launcher/ReleaseNotesWindow.xaml
new file mode 100644
index 000000000..132de63c8
--- /dev/null
+++ b/Flow.Launcher/ReleaseNotesWindow.xaml
@@ -0,0 +1,168 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Flow.Launcher/ReleaseNotesWindow.xaml.cs b/Flow.Launcher/ReleaseNotesWindow.xaml.cs
new file mode 100644
index 000000000..18c67ac5b
--- /dev/null
+++ b/Flow.Launcher/ReleaseNotesWindow.xaml.cs
@@ -0,0 +1,149 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Input;
+using Flow.Launcher.Infrastructure.Http;
+
+namespace Flow.Launcher
+{
+ public partial class ReleaseNotesWindow : Window
+ {
+ public ReleaseNotesWindow()
+ {
+ InitializeComponent();
+ }
+
+ #region Window Events
+
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD100:Avoid async void methods", Justification = "")]
+ private async void Window_Loaded(object sender, RoutedEventArgs e)
+ {
+ RefreshMaximizeRestoreButton();
+ MarkdownViewer.Markdown = await GetReleaseNotesMarkdownAsync();
+ }
+
+ private void OnCloseExecuted(object sender, ExecutedRoutedEventArgs e)
+ {
+ Close();
+ }
+
+ #endregion
+
+ #region Window Custom TitleBar
+
+ private void OnMinimizeButtonClick(object sender, RoutedEventArgs e)
+ {
+ WindowState = WindowState.Minimized;
+ }
+
+ private void OnMaximizeRestoreButtonClick(object sender, RoutedEventArgs e)
+ {
+ WindowState = WindowState switch
+ {
+ WindowState.Maximized => WindowState.Normal,
+ _ => WindowState.Maximized
+ };
+ }
+
+ private void OnCloseButtonClick(object sender, RoutedEventArgs e)
+ {
+ Close();
+ }
+
+ private void RefreshMaximizeRestoreButton()
+ {
+ if (WindowState == WindowState.Maximized)
+ {
+ MaximizeButton.Visibility = Visibility.Hidden;
+ RestoreButton.Visibility = Visibility.Visible;
+ }
+ else
+ {
+ MaximizeButton.Visibility = Visibility.Visible;
+ RestoreButton.Visibility = Visibility.Hidden;
+ }
+ }
+
+ private void Window_StateChanged(object sender, EventArgs e)
+ {
+ RefreshMaximizeRestoreButton();
+ }
+
+ #endregion
+
+ #region Release Notes
+
+ private static async Task GetReleaseNotesMarkdownAsync()
+ {
+ var releaseNotesJSON = await Http.GetStringAsync("https://api.github.com/repos/Flow-Launcher/Flow.Launcher/releases");
+ var releases = JsonSerializer.Deserialize>(releaseNotesJSON);
+
+ // Get the latest releases
+ var latestReleases = releases.OrderByDescending(release => release.PublishedDate).Take(3);
+
+ // Build the release notes in Markdown format
+ var releaseNotesHtmlBuilder = new StringBuilder(string.Empty);
+ foreach (var release in latestReleases)
+ {
+ releaseNotesHtmlBuilder.AppendLine("# " + release.Name);
+
+ // Add unit for images: Replace
with
+ var notes = ImageUnitRegex().Replace(release.ReleaseNotes, m =>
+ {
+ var prefix = m.Groups[1].Value;
+ var widthValue = m.Groups[2].Value;
+ var quote = m.Groups[3].Value;
+ var suffix = m.Groups[4].Value;
+ // Only replace if width is number like 500 without units like 500px
+ if (IsNumber(widthValue))
+ return $"{prefix}{widthValue}px{quote}{suffix}";
+ return m.Value;
+ });
+
+ releaseNotesHtmlBuilder.AppendLine(notes);
+ releaseNotesHtmlBuilder.AppendLine(" ");
+ }
+
+ return releaseNotesHtmlBuilder.ToString();
+ }
+
+ private static bool IsNumber(string input)
+ {
+ if (string.IsNullOrEmpty(input))
+ return false;
+
+ foreach (char c in input)
+ {
+ if (!char.IsDigit(c))
+ return false;
+ }
+ return true;
+ }
+
+ private sealed class GitHubReleaseInfo
+ {
+ [JsonPropertyName("published_at")]
+ public DateTimeOffset PublishedDate { get; set; }
+
+ [JsonPropertyName("name")]
+ public string Name { get; set; }
+
+ [JsonPropertyName("tag_name")]
+ public string TagName { get; set; }
+
+ [JsonPropertyName("body")]
+ public string ReleaseNotes { get; set; }
+ }
+
+ [GeneratedRegex("(
]*width\\s*=\\s*[\"']?)(\\d+)([\"']?)([^>]*>)", RegexOptions.IgnoreCase, "en-GB")]
+ private static partial Regex ImageUnitRegex();
+
+ #endregion
+ }
+}
From 7117ba05ee4ef544f4bc0c7c648fa3e5f8c25971 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 6 Jun 2025 23:08:41 +0800
Subject: [PATCH 1461/1697] Test release notes window
---
Flow.Launcher/MainWindow.xaml.cs | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index a77d6471c..b266d3dc0 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -132,6 +132,9 @@ namespace Flow.Launcher
welcomeWindow.Show();
}
+ var releaseNotesWindow = new ReleaseNotesWindow();
+ releaseNotesWindow.Show();
+
// Initialize place holder
SetupPlaceholderText();
_viewModel.PlaceholderText = _settings.PlaceholderText;
From c241d21a4a9259a3ce1eb50f21b0624c6780cba0 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 6 Jun 2025 23:51:26 +0800
Subject: [PATCH 1462/1697] Fix height
---
Flow.Launcher/ReleaseNotesWindow.xaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/ReleaseNotesWindow.xaml b/Flow.Launcher/ReleaseNotesWindow.xaml
index 132de63c8..e61986aea 100644
--- a/Flow.Launcher/ReleaseNotesWindow.xaml
+++ b/Flow.Launcher/ReleaseNotesWindow.xaml
@@ -157,7 +157,7 @@
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="5"
- MaxHeight="510"
+ Height="510"
Margin="15 0 20 0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
From af0e1180a5cbc18cba3090f10595e58ab12e7ac6 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 6 Jun 2025 23:52:34 +0800
Subject: [PATCH 1463/1697] Use loaded event & Add style
---
Flow.Launcher/ReleaseNotesWindow.xaml | 3 ++-
Flow.Launcher/ReleaseNotesWindow.xaml.cs | 17 ++++++++++++++---
2 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher/ReleaseNotesWindow.xaml b/Flow.Launcher/ReleaseNotesWindow.xaml
index e61986aea..7b2e5f7e7 100644
--- a/Flow.Launcher/ReleaseNotesWindow.xaml
+++ b/Flow.Launcher/ReleaseNotesWindow.xaml
@@ -161,7 +161,8 @@
Margin="15 0 20 0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
- ClickAction="SafetyDisplayWithRelativePath" />
+ ClickAction="SafetyDisplayWithRelativePath"
+ Loaded="MarkdownViewer_Loaded" />
diff --git a/Flow.Launcher/ReleaseNotesWindow.xaml.cs b/Flow.Launcher/ReleaseNotesWindow.xaml.cs
index 18c67ac5b..4f0c1a9ce 100644
--- a/Flow.Launcher/ReleaseNotesWindow.xaml.cs
+++ b/Flow.Launcher/ReleaseNotesWindow.xaml.cs
@@ -9,6 +9,7 @@ using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using Flow.Launcher.Infrastructure.Http;
+using MdXaml;
namespace Flow.Launcher
{
@@ -21,11 +22,9 @@ namespace Flow.Launcher
#region Window Events
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD100:Avoid async void methods", Justification = "")]
- private async void Window_Loaded(object sender, RoutedEventArgs e)
+ private void Window_Loaded(object sender, RoutedEventArgs e)
{
RefreshMaximizeRestoreButton();
- MarkdownViewer.Markdown = await GetReleaseNotesMarkdownAsync();
}
private void OnCloseExecuted(object sender, ExecutedRoutedEventArgs e)
@@ -82,6 +81,11 @@ namespace Flow.Launcher
private static async Task GetReleaseNotesMarkdownAsync()
{
var releaseNotesJSON = await Http.GetStringAsync("https://api.github.com/repos/Flow-Launcher/Flow.Launcher/releases");
+
+ if (string.IsNullOrEmpty(releaseNotesJSON))
+ {
+ return string.Empty;
+ }
var releases = JsonSerializer.Deserialize>(releaseNotesJSON);
// Get the latest releases
@@ -145,5 +149,12 @@ namespace Flow.Launcher
private static partial Regex ImageUnitRegex();
#endregion
+
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD100:Avoid async void methods", Justification = "")]
+ private async void MarkdownViewer_Loaded(object sender, RoutedEventArgs e)
+ {
+ MarkdownViewer.MarkdownStyle = MarkdownStyle.GithubLike;
+ MarkdownViewer.Markdown = await GetReleaseNotesMarkdownAsync();
+ }
}
}
From 02496214ea2cabbd0037bc83f3e9e03125311222 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 7 Jun 2025 00:07:44 +0800
Subject: [PATCH 1464/1697] Add progress ring
---
Flow.Launcher/ReleaseNotesWindow.xaml | 23 ++++++++++++++++
Flow.Launcher/ReleaseNotesWindow.xaml.cs | 34 +++++++++++++++++++++---
2 files changed, 53 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher/ReleaseNotesWindow.xaml b/Flow.Launcher/ReleaseNotesWindow.xaml
index 7b2e5f7e7..f70fa6f5c 100644
--- a/Flow.Launcher/ReleaseNotesWindow.xaml
+++ b/Flow.Launcher/ReleaseNotesWindow.xaml
@@ -163,6 +163,29 @@
VerticalAlignment="Stretch"
ClickAction="SafetyDisplayWithRelativePath"
Loaded="MarkdownViewer_Loaded" />
+
+
+
+
+
+
diff --git a/Flow.Launcher/ReleaseNotesWindow.xaml.cs b/Flow.Launcher/ReleaseNotesWindow.xaml.cs
index 4f0c1a9ce..8881f3fb6 100644
--- a/Flow.Launcher/ReleaseNotesWindow.xaml.cs
+++ b/Flow.Launcher/ReleaseNotesWindow.xaml.cs
@@ -81,7 +81,7 @@ namespace Flow.Launcher
private static async Task GetReleaseNotesMarkdownAsync()
{
var releaseNotesJSON = await Http.GetStringAsync("https://api.github.com/repos/Flow-Launcher/Flow.Launcher/releases");
-
+
if (string.IsNullOrEmpty(releaseNotesJSON))
{
return string.Empty;
@@ -150,11 +150,37 @@ namespace Flow.Launcher
#endregion
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD100:Avoid async void methods", Justification = "")]
- private async void MarkdownViewer_Loaded(object sender, RoutedEventArgs e)
+ private void MarkdownViewer_Loaded(object sender, RoutedEventArgs e)
{
MarkdownViewer.MarkdownStyle = MarkdownStyle.GithubLike;
- MarkdownViewer.Markdown = await GetReleaseNotesMarkdownAsync();
+ RefreshMarkdownViewer();
+ }
+
+ private void RefreshButton_Click(object sender, RoutedEventArgs e)
+ {
+ RefreshButton.Visibility = Visibility.Collapsed;
+ RefreshProgressRing.Visibility = Visibility.Visible;
+ RefreshMarkdownViewer();
+ }
+
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD100:Avoid async void methods", Justification = "")]
+ private async void RefreshMarkdownViewer()
+ {
+ var output = await GetReleaseNotesMarkdownAsync().ConfigureAwait(false);
+
+ Application.Current.Dispatcher.Invoke(() =>
+ {
+ RefreshProgressRing.Visibility = Visibility.Collapsed;
+ if (string.IsNullOrEmpty(output))
+ {
+ RefreshButton.Visibility = Visibility.Visible;
+ }
+ else
+ {
+ RefreshButton.Visibility = Visibility.Collapsed;
+ MarkdownViewer.Markdown = output;
+ }
+ });
}
}
}
From 1ef8d65dce3011f6902019d25ed32df6fb9de313 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 7 Jun 2025 00:07:52 +0800
Subject: [PATCH 1465/1697] Adjust size
---
Flow.Launcher/ReleaseNotesWindow.xaml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/ReleaseNotesWindow.xaml b/Flow.Launcher/ReleaseNotesWindow.xaml
index f70fa6f5c..3df1a3c00 100644
--- a/Flow.Launcher/ReleaseNotesWindow.xaml
+++ b/Flow.Launcher/ReleaseNotesWindow.xaml
@@ -173,8 +173,8 @@
Margin="15 0 20 0">
From 1f61d934f81ed5aaf796e08c666c32469da052ac Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 7 Jun 2025 00:12:54 +0800
Subject: [PATCH 1466/1697] Follow theme change
---
Flow.Launcher/ReleaseNotesWindow.xaml | 1 +
Flow.Launcher/ReleaseNotesWindow.xaml.cs | 25 ++++++++++++++++++++++++
2 files changed, 26 insertions(+)
diff --git a/Flow.Launcher/ReleaseNotesWindow.xaml b/Flow.Launcher/ReleaseNotesWindow.xaml
index 3df1a3c00..b274981a3 100644
--- a/Flow.Launcher/ReleaseNotesWindow.xaml
+++ b/Flow.Launcher/ReleaseNotesWindow.xaml
@@ -11,6 +11,7 @@
Title="{DynamicResource releaseNotes}"
Width="700"
Background="{DynamicResource PopuBGColor}"
+ Closed="Window_Closed"
Foreground="{DynamicResource PopupTextColor}"
Loaded="Window_Loaded"
ResizeMode="CanResize"
diff --git a/Flow.Launcher/ReleaseNotesWindow.xaml.cs b/Flow.Launcher/ReleaseNotesWindow.xaml.cs
index 8881f3fb6..bf034c74f 100644
--- a/Flow.Launcher/ReleaseNotesWindow.xaml.cs
+++ b/Flow.Launcher/ReleaseNotesWindow.xaml.cs
@@ -8,6 +8,7 @@ using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
+using System.Windows.Media;
using Flow.Launcher.Infrastructure.Http;
using MdXaml;
@@ -18,6 +19,7 @@ namespace Flow.Launcher
public ReleaseNotesWindow()
{
InitializeComponent();
+ ModernWpf.ThemeManager.Current.ActualApplicationThemeChanged += ThemeManager_ActualApplicationThemeChanged;
}
#region Window Events
@@ -25,6 +27,7 @@ namespace Flow.Launcher
private void Window_Loaded(object sender, RoutedEventArgs e)
{
RefreshMaximizeRestoreButton();
+ ThemeManager_ActualApplicationThemeChanged(null, null);
}
private void OnCloseExecuted(object sender, ExecutedRoutedEventArgs e)
@@ -182,5 +185,27 @@ namespace Flow.Launcher
}
});
}
+
+ private void Window_Closed(object sender, EventArgs e)
+ {
+ ModernWpf.ThemeManager.Current.ActualApplicationThemeChanged -= ThemeManager_ActualApplicationThemeChanged;
+ }
+
+ private void ThemeManager_ActualApplicationThemeChanged(ModernWpf.ThemeManager sender, object args)
+ {
+ Application.Current.Dispatcher.Invoke(() =>
+ {
+ if (ModernWpf.ThemeManager.Current.ActualApplicationTheme == ModernWpf.ApplicationTheme.Light)
+ {
+ MarkdownViewer.Foreground = Brushes.Black;
+ MarkdownViewer.Background = Brushes.White;
+ }
+ else
+ {
+ MarkdownViewer.Foreground = Brushes.White;
+ MarkdownViewer.Background = Brushes.Black;
+ }
+ });
+ }
}
}
From 394fd1d44c06446d94eca4e6a684a8bf9c6391d1 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 7 Jun 2025 10:13:45 +0800
Subject: [PATCH 1467/1697] Support light/dark style
---
Flow.Launcher/ReleaseNotesWindow.xaml.cs | 4 +-
.../Resources/CustomControlTemplate.xaml | 399 ++++++++++++++++--
2 files changed, 369 insertions(+), 34 deletions(-)
diff --git a/Flow.Launcher/ReleaseNotesWindow.xaml.cs b/Flow.Launcher/ReleaseNotesWindow.xaml.cs
index bf034c74f..c5130254a 100644
--- a/Flow.Launcher/ReleaseNotesWindow.xaml.cs
+++ b/Flow.Launcher/ReleaseNotesWindow.xaml.cs
@@ -10,7 +10,6 @@ using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using Flow.Launcher.Infrastructure.Http;
-using MdXaml;
namespace Flow.Launcher
{
@@ -155,7 +154,6 @@ namespace Flow.Launcher
private void MarkdownViewer_Loaded(object sender, RoutedEventArgs e)
{
- MarkdownViewer.MarkdownStyle = MarkdownStyle.GithubLike;
RefreshMarkdownViewer();
}
@@ -197,11 +195,13 @@ namespace Flow.Launcher
{
if (ModernWpf.ThemeManager.Current.ActualApplicationTheme == ModernWpf.ApplicationTheme.Light)
{
+ MarkdownViewer.MarkdownStyle = (Style)Application.Current.Resources["DocumentStyleGithubLikeLight"];
MarkdownViewer.Foreground = Brushes.Black;
MarkdownViewer.Background = Brushes.White;
}
else
{
+ MarkdownViewer.MarkdownStyle = (Style)Application.Current.Resources["DocumentStyleGithubLikeDark"];
MarkdownViewer.Foreground = Brushes.White;
MarkdownViewer.Background = Brushes.Black;
}
diff --git a/Flow.Launcher/Resources/CustomControlTemplate.xaml b/Flow.Launcher/Resources/CustomControlTemplate.xaml
index cdaadd45a..6fd964867 100644
--- a/Flow.Launcher/Resources/CustomControlTemplate.xaml
+++ b/Flow.Launcher/Resources/CustomControlTemplate.xaml
@@ -2408,12 +2408,15 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
From 84e91d2bdc37b7f2e5746e961e0a16816618e1b3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 7 Jun 2025 10:14:37 +0800
Subject: [PATCH 1468/1697] Fix display issue
---
Flow.Launcher/ReleaseNotesWindow.xaml.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/ReleaseNotesWindow.xaml.cs b/Flow.Launcher/ReleaseNotesWindow.xaml.cs
index c5130254a..e7e766f60 100644
--- a/Flow.Launcher/ReleaseNotesWindow.xaml.cs
+++ b/Flow.Launcher/ReleaseNotesWindow.xaml.cs
@@ -113,7 +113,7 @@ namespace Flow.Launcher
});
releaseNotesHtmlBuilder.AppendLine(notes);
- releaseNotesHtmlBuilder.AppendLine(" ");
+ releaseNotesHtmlBuilder.AppendLine();
}
return releaseNotesHtmlBuilder.ToString();
From eee57e29d047074525f118df5b73456c84f5cfb3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 7 Jun 2025 10:34:26 +0800
Subject: [PATCH 1469/1697] Improve code quality
---
Flow.Launcher/ReleaseNotesWindow.xaml.cs | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/Flow.Launcher/ReleaseNotesWindow.xaml.cs b/Flow.Launcher/ReleaseNotesWindow.xaml.cs
index e7e766f60..95cb76675 100644
--- a/Flow.Launcher/ReleaseNotesWindow.xaml.cs
+++ b/Flow.Launcher/ReleaseNotesWindow.xaml.cs
@@ -34,6 +34,11 @@ namespace Flow.Launcher
Close();
}
+ private void Window_Closed(object sender, EventArgs e)
+ {
+ ModernWpf.ThemeManager.Current.ActualApplicationThemeChanged -= ThemeManager_ActualApplicationThemeChanged;
+ }
+
#endregion
#region Window Custom TitleBar
@@ -99,7 +104,9 @@ namespace Flow.Launcher
{
releaseNotesHtmlBuilder.AppendLine("# " + release.Name);
- // Add unit for images: Replace
with
+ // Because MdXaml.Html package cannot correctly render images without units,
+ // We need to manually add unit for images
+ // E.g. Replace
with
var notes = ImageUnitRegex().Replace(release.ReleaseNotes, m =>
{
var prefix = m.Groups[1].Value;
@@ -184,11 +191,6 @@ namespace Flow.Launcher
});
}
- private void Window_Closed(object sender, EventArgs e)
- {
- ModernWpf.ThemeManager.Current.ActualApplicationThemeChanged -= ThemeManager_ActualApplicationThemeChanged;
- }
-
private void ThemeManager_ActualApplicationThemeChanged(ModernWpf.ThemeManager sender, object args)
{
Application.Current.Dispatcher.Invoke(() =>
From 458a8b3efb13c008d0d7ef3c0fced60dd39975b4 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 7 Jun 2025 11:11:40 +0800
Subject: [PATCH 1470/1697] Add mdxaml plugins
---
Flow.Launcher/Flow.Launcher.csproj | 4 ++++
Flow.Launcher/ReleaseNotesWindow.xaml | 3 ++-
Flow.Launcher/Resources/CustomControlTemplate.xaml | 10 ++++++++++
3 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj
index 4580798b2..d75d15a21 100644
--- a/Flow.Launcher/Flow.Launcher.csproj
+++ b/Flow.Launcher/Flow.Launcher.csproj
@@ -91,6 +91,10 @@
+
+
+
+
diff --git a/Flow.Launcher/ReleaseNotesWindow.xaml b/Flow.Launcher/ReleaseNotesWindow.xaml
index b274981a3..2cd47c619 100644
--- a/Flow.Launcher/ReleaseNotesWindow.xaml
+++ b/Flow.Launcher/ReleaseNotesWindow.xaml
@@ -163,7 +163,8 @@
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
ClickAction="SafetyDisplayWithRelativePath"
- Loaded="MarkdownViewer_Loaded" />
+ Loaded="MarkdownViewer_Loaded"
+ Plugins="{StaticResource MdXamlPlugins}" />
@@ -5761,6 +5765,12 @@
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -118,14 +117,14 @@
x:Name="btnCancel"
Width="145"
Height="30"
- Margin="10 0 5 0"
+ Margin="10 0 10 0"
Click="BtnCancel_OnClick"
Content="{DynamicResource cancel}" />
diff --git a/Flow.Launcher/ActionKeywords.xaml.cs b/Flow.Launcher/ActionKeywords.xaml.cs
index 9420b4c38..8e05686c9 100644
--- a/Flow.Launcher/ActionKeywords.xaml.cs
+++ b/Flow.Launcher/ActionKeywords.xaml.cs
@@ -20,7 +20,9 @@ namespace Flow.Launcher
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);
+ tbAction.Text = tbOldActionKeyword.Text;
+ tbAction.SelectAll();
tbAction.Focus();
}
@@ -33,38 +35,39 @@ namespace Flow.Launcher
{
var oldActionKeywords = _plugin.Metadata.ActionKeywords;
- var newActionKeywords = tbAction.Text.Split(Query.ActionKeywordSeparator).ToList();
- newActionKeywords.RemoveAll(string.IsNullOrEmpty);
- newActionKeywords = newActionKeywords.Distinct().ToList();
+ var newActionKeywords = tbAction.Text.Split(Query.ActionKeywordSeparator)
+ .Where(s => !string.IsNullOrEmpty(s))
+ .Distinct()
+ .ToList();
newActionKeywords = newActionKeywords.Count > 0 ? newActionKeywords : new() { Query.GlobalPluginWildcardSign };
var addedActionKeywords = newActionKeywords.Except(oldActionKeywords).ToList();
var removedActionKeywords = oldActionKeywords.Except(newActionKeywords).ToList();
- if (!addedActionKeywords.Any(App.API.ActionKeywordAssigned))
+
+ if (addedActionKeywords.Any(App.API.ActionKeywordAssigned))
{
- if (oldActionKeywords.Count != newActionKeywords.Count)
- {
- ReplaceActionKeyword(_plugin.Metadata.ID, removedActionKeywords, addedActionKeywords);
- return;
- }
+ App.API.ShowMsgBox(App.API.GetTranslation("newActionKeywordsHasBeenAssigned"));
+ return;
+ }
- var sortedOldActionKeywords = oldActionKeywords.OrderBy(s => s).ToList();
- var sortedNewActionKeywords = newActionKeywords.OrderBy(s => s).ToList();
+ if (oldActionKeywords.Count != newActionKeywords.Count)
+ {
+ ReplaceActionKeyword(_plugin.Metadata.ID, removedActionKeywords, addedActionKeywords);
+ return;
+ }
- if (sortedOldActionKeywords.SequenceEqual(sortedNewActionKeywords))
- {
- // User just changes the sequence of action keywords
- App.API.ShowMsgBox(App.API.GetTranslation("newActionKeywordsSameAsOld"));
- }
- else
- {
- ReplaceActionKeyword(_plugin.Metadata.ID, removedActionKeywords, addedActionKeywords);
- }
+ var sortedOldActionKeywords = oldActionKeywords.OrderBy(s => s).ToList();
+ var sortedNewActionKeywords = newActionKeywords.OrderBy(s => s).ToList();
+
+ if (sortedOldActionKeywords.SequenceEqual(sortedNewActionKeywords))
+ {
+ // User just changes the sequence of action keywords
+ App.API.ShowMsgBox(App.API.GetTranslation("newActionKeywordsSameAsOld"));
}
else
{
- App.API.ShowMsgBox(App.API.GetTranslation("newActionKeywordsHasBeenAssigned"));
+ ReplaceActionKeyword(_plugin.Metadata.ID, removedActionKeywords, addedActionKeywords);
}
}
From 393c861660edf2a40bfba8b12ac0f39013bf5e2b Mon Sep 17 00:00:00 2001
From: DB P
Date: Wed, 11 Jun 2025 15:26:15 +0900
Subject: [PATCH 1521/1697] Adjust Margin
---
Flow.Launcher/ActionKeywords.xaml | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/Flow.Launcher/ActionKeywords.xaml b/Flow.Launcher/ActionKeywords.xaml
index 8636eb4c2..7fed8a629 100644
--- a/Flow.Launcher/ActionKeywords.xaml
+++ b/Flow.Launcher/ActionKeywords.xaml
@@ -66,7 +66,7 @@
Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="2"
- Margin="26 0 26 18"
+ Margin="26 0 26 10"
FontSize="14"
Text="{DynamicResource actionkeyword_tips}"
TextAlignment="Left"
@@ -83,7 +83,7 @@
x:Name="tbOldActionKeyword"
Grid.Row="3"
Grid.Column="1"
- Margin="10 10 26 10"
+ Margin="10 10 26 6"
VerticalAlignment="Center"
FontSize="14"
FontWeight="SemiBold"
@@ -94,7 +94,7 @@
@@ -102,12 +102,12 @@
x:Name="tbAction"
Grid.Row="4"
Grid.Column="1"
- Margin="10 10 26 10"
+ Margin="10 6 26 10"
VerticalAlignment="Center" />
Date: Wed, 11 Jun 2025 15:27:55 +0900
Subject: [PATCH 1522/1697] Adjust Button Size
---
Flow.Launcher/ActionKeywords.xaml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/ActionKeywords.xaml b/Flow.Launcher/ActionKeywords.xaml
index 7fed8a629..dfea00f8f 100644
--- a/Flow.Launcher/ActionKeywords.xaml
+++ b/Flow.Launcher/ActionKeywords.xaml
@@ -116,14 +116,14 @@
From 8e740c8e3a3cf0db30d8f579b957459dfc1d977b Mon Sep 17 00:00:00 2001
From: Stefan Roelofs
Date: Wed, 11 Jun 2025 08:44:21 +0200
Subject: [PATCH 1523/1697] Automatic refactor by XamlStyler extension
---
Flow.Launcher/ActionKeywords.xaml | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher/ActionKeywords.xaml b/Flow.Launcher/ActionKeywords.xaml
index dfea00f8f..5af76f37f 100644
--- a/Flow.Launcher/ActionKeywords.xaml
+++ b/Flow.Launcher/ActionKeywords.xaml
@@ -107,8 +107,9 @@
From 0f94ec673a36fa0eb0884b7e68bba3c4593e2192 Mon Sep 17 00:00:00 2001
From: DB P
Date: Wed, 11 Jun 2025 15:54:38 +0900
Subject: [PATCH 1524/1697] Skip release notes notification for developer
builds
---
Flow.Launcher/MainWindow.xaml.cs | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index e527ab57b..f4d7ad8eb 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -137,12 +137,11 @@ namespace Flow.Launcher
welcomeWindow.Show();
}
- if (_settings.ReleaseNotesVersion != Constant.Version)
+ if (Constant.Version != "1.0.0" && _settings.ReleaseNotesVersion != Constant.Version) // Skip release notes notification for developer builds (version 1.0.0)
{
// Update release notes version
_settings.ReleaseNotesVersion = Constant.Version;
-
- // Display message box with button
+ // Show release note popup with button
App.API.ShowMsgWithButton(
string.Format(App.API.GetTranslation("appUpdateTitle"), Constant.Version),
App.API.GetTranslation("appUpdateButtonContent"),
From 3220a0b8f3db3c46771a960960b24eb35aa8f0fa Mon Sep 17 00:00:00 2001
From: Jeremy
Date: Wed, 11 Jun 2025 21:10:56 +1000
Subject: [PATCH 1525/1697] remove on tag deployment & change NuGet publish to
on master push
---
appveyor.yml | 11 +----------
1 file changed, 1 insertion(+), 10 deletions(-)
diff --git a/appveyor.yml b/appveyor.yml
index fa0b5956b..8fba05252 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -62,7 +62,7 @@ deploy:
api_key:
secure: sCSd5JWgdzJWDa9kpqECut5ACPKZqcoxKU8ERKC00k7VIjig3/+nFV5zzTcGb0w3
on:
- APPVEYOR_REPO_TAG: true
+ branch: master
- provider: GitHub
repository: Flow-Launcher/Prereleases
@@ -84,12 +84,3 @@ deploy:
force_update: true
on:
branch: master
-
- - provider: GitHub
- release: v$(flowVersion)
- auth_token:
- secure: ij4UeXUYQBDJxn2YRAAhUOjklOGVKDB87Hn5J8tKIzj13yatoI7sLM666QDQFEgv
- artifact: Squirrel Installer, Portable Version, Squirrel nupkg, Squirrel RELEASES
- force_update: true
- on:
- APPVEYOR_REPO_TAG: true
From 6f516ee1207bc153281503e0e053e7815fee79da Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 11 Jun 2025 21:14:05 +0800
Subject: [PATCH 1526/1697] Change code comments
---
.../FirefoxBookmarkLoader.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
index dcf7763c3..f214997c3 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
@@ -343,9 +343,9 @@ public class FirefoxBookmarkLoader : FirefoxBookmarkLoaderBase
Locked=1
[Profile2]
- Name=newblahprofile
+ Name=dummyprofile
IsRelative=0
- Path=C:\t6h2yuq8.newblahprofile <== Note this is a custom location path for the profile user can set, we need to cater for this in code.
+ Path=C:\t6h2yuq8.dummyprofile <== Note this is a custom location path for the profile user can set, we need to cater for this in code.
[Profile1]
Name=default
From b166b18ab73c2cc15e574d5a375efcd406a8ef4b Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 12 Jun 2025 14:25:10 +0800
Subject: [PATCH 1527/1697] Add preview information back for external preview
---
Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
index a16d0c5f3..e87d2df97 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
@@ -101,6 +101,10 @@ namespace Flow.Launcher.Plugin.Explorer.Search
AutoCompleteText = GetAutoCompleteText(title, query, path, ResultType.Folder),
TitleHighlightData = Context.API.FuzzySearch(query.Search, title).MatchData,
CopyText = path,
+ Preview = new Result.PreviewInfo
+ {
+ FilePath = path,
+ },
PreviewPanel = new Lazy(() => new PreviewPanel(Settings, path, ResultType.Folder)),
Action = c =>
{
From b6cca4547cf87733a1adb3c60edd8c86856a69cb Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 12 Jun 2025 16:27:48 +0800
Subject: [PATCH 1528/1697] Fix typos
---
.../FirefoxBookmarkLoader.cs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
index f214997c3..8dffeecdc 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
@@ -365,21 +365,21 @@ public class FirefoxBookmarkLoader : FirefoxBookmarkLoaderBase
// Seen in the example above, the IsRelative attribute is always above the Path attribute
var relativePath = Path.Combine(defaultProfileFolderName, "places.sqlite");
- var absoluePath = Path.Combine(profileFolderPath, relativePath);
+ var absolutePath = Path.Combine(profileFolderPath, relativePath);
// If the index is out of range, it means that the default profile is in a custom location or the file is malformed
// If the profile is in a custom location, we need to check
if (indexOfDefaultProfileAttributePath - 1 < 0 ||
indexOfDefaultProfileAttributePath - 1 >= lines.Count)
{
- return Directory.Exists(absoluePath) ? absoluePath : relativePath;
+ return Directory.Exists(absolutePath) ? absolutePath : relativePath;
}
var relativeAttribute = lines[indexOfDefaultProfileAttributePath - 1];
// See above, the profile is located in a custom location, path is not relative, so IsRelative=0
return (relativeAttribute == "0" || relativeAttribute == "IsRelative=0")
- ? relativePath : absoluePath;
+ ? relativePath : absolutePath;
}
}
From a34a4790b70e269d6ef0bbca7fece75f6f03741b Mon Sep 17 00:00:00 2001
From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Fri, 13 Jun 2025 00:21:49 +0800
Subject: [PATCH 1529/1697] Delete
Flow.Launcher/Properties/Resources.fr-FR.resx
---
Flow.Launcher/Properties/Resources.fr-FR.resx | 130 ------------------
1 file changed, 130 deletions(-)
delete mode 100644 Flow.Launcher/Properties/Resources.fr-FR.resx
diff --git a/Flow.Launcher/Properties/Resources.fr-FR.resx b/Flow.Launcher/Properties/Resources.fr-FR.resx
deleted file mode 100644
index ca0f66f53..000000000
--- a/Flow.Launcher/Properties/Resources.fr-FR.resx
+++ /dev/null
@@ -1,130 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 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
From cce8d1ac23e5b3a57476e9f447b1c0b2bdcbfb88 Mon Sep 17 00:00:00 2001
From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Fri, 13 Jun 2025 00:24:40 +0800
Subject: [PATCH 1530/1697] Delete
Flow.Launcher/Properties/Resources.he-IL.resx
---
Flow.Launcher/Properties/Resources.he-IL.resx | 130 ------------------
1 file changed, 130 deletions(-)
delete mode 100644 Flow.Launcher/Properties/Resources.he-IL.resx
diff --git a/Flow.Launcher/Properties/Resources.he-IL.resx b/Flow.Launcher/Properties/Resources.he-IL.resx
deleted file mode 100644
index ca0f66f53..000000000
--- a/Flow.Launcher/Properties/Resources.he-IL.resx
+++ /dev/null
@@ -1,130 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 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
From eb7a89292b2d61126ede55baf1affb3340bb28fa Mon Sep 17 00:00:00 2001
From: Jeremy
Date: Fri, 13 Jun 2025 22:02:34 +1000
Subject: [PATCH 1531/1697] update OpenUrl method summary
---
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index b87cc52d0..09c402bcf 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -319,13 +319,15 @@ namespace Flow.Launcher.Plugin
public void OpenWebUrl(string url, bool? inPrivate = null);
///
- /// Opens the URL with the given Uri object.
+ /// Opens the URL with the given Uri object in browser if scheme is Http or Https.
+ /// If the URL is a local file, it will instead be opened with the default application for that file type.
/// The browser and mode used is based on what's configured in Flow's default browser settings.
///
public void OpenUrl(Uri url, bool? inPrivate = null);
///
- /// Opens the URL with the given string.
+ /// Opens the URL with the given string in browser if scheme is Http or Https.
+ /// If the URL is a local file, it will instead be opened with the default application for that file type.
/// The browser and mode used is based on what's configured in Flow's default browser settings.
/// Non-C# plugins should use this method.
///
From a77c80f7c140ab76e764a6d70e2924f46297bd84 Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Fri, 13 Jun 2025 22:37:36 +1000
Subject: [PATCH 1532/1697] New Crowdin updates (#3615)
---
Flow.Launcher/Languages/ar.xaml | 10 ++++
Flow.Launcher/Languages/cs.xaml | 10 ++++
Flow.Launcher/Languages/da.xaml | 12 +++-
Flow.Launcher/Languages/de.xaml | 10 ++++
Flow.Launcher/Languages/es-419.xaml | 10 ++++
Flow.Launcher/Languages/es.xaml | 12 +++-
Flow.Launcher/Languages/fr.xaml | 12 +++-
Flow.Launcher/Languages/he.xaml | 10 ++++
Flow.Launcher/Languages/it.xaml | 10 ++++
Flow.Launcher/Languages/ja.xaml | 10 ++++
Flow.Launcher/Languages/ko.xaml | 10 ++++
Flow.Launcher/Languages/nb.xaml | 10 ++++
Flow.Launcher/Languages/nl.xaml | 10 ++++
Flow.Launcher/Languages/pl.xaml | 10 ++++
Flow.Launcher/Languages/pt-br.xaml | 10 ++++
Flow.Launcher/Languages/pt-pt.xaml | 14 ++++-
Flow.Launcher/Languages/ru.xaml | 10 ++++
Flow.Launcher/Languages/sk.xaml | 14 ++++-
Flow.Launcher/Languages/sr.xaml | 10 ++++
Flow.Launcher/Languages/tr.xaml | 60 +++++++++++--------
Flow.Launcher/Languages/uk-UA.xaml | 10 ++++
Flow.Launcher/Languages/vi.xaml | 10 ++++
Flow.Launcher/Languages/zh-cn.xaml | 12 +++-
Flow.Launcher/Languages/zh-tw.xaml | 10 ++++
.../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/ar.xaml | 11 ++++
.../Languages/cs.xaml | 11 ++++
.../Languages/da.xaml | 11 ++++
.../Languages/de.xaml | 11 ++++
.../Languages/es-419.xaml | 11 ++++
.../Languages/es.xaml | 11 ++++
.../Languages/fr.xaml | 11 ++++
.../Languages/he.xaml | 11 ++++
.../Languages/it.xaml | 11 ++++
.../Languages/ja.xaml | 11 ++++
.../Languages/ko.xaml | 11 ++++
.../Languages/nb.xaml | 11 ++++
.../Languages/nl.xaml | 11 ++++
.../Languages/pl.xaml | 11 ++++
.../Languages/pt-br.xaml | 11 ++++
.../Languages/pt-pt.xaml | 13 +++-
.../Languages/ru.xaml | 11 ++++
.../Languages/sk.xaml | 11 ++++
.../Languages/sr.xaml | 11 ++++
.../Languages/tr.xaml | 23 +++++--
.../Languages/uk-UA.xaml | 11 ++++
.../Languages/vi.xaml | 11 ++++
.../Languages/zh-cn.xaml | 11 ++++
.../Languages/zh-tw.xaml | 11 ++++
.../Languages/tr.xaml | 10 ++--
.../Languages/tr.xaml | 24 ++++----
.../Languages/tr.xaml | 8 +--
.../Properties/Resources.pt-PT.resx | 6 +-
76 files changed, 616 insertions(+), 64 deletions(-)
diff --git a/Flow.Launcher/Languages/ar.xaml b/Flow.Launcher/Languages/ar.xaml
index 88e8fbc61..b0d4b6818 100644
--- a/Flow.Launcher/Languages/ar.xaml
+++ b/Flow.Launcher/Languages/ar.xaml
@@ -136,6 +136,8 @@
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.
+ Show Search Window at Topmost
+ Show search window above other windows
البحث عن إضافة
@@ -370,6 +372,13 @@
Info
Setting Window Font
+
+ See more release notes on GitHub
+ Failed to fetch release notes
+ Please check your network connection or ensure GitHub is accessible
+ Flow Launcher has been updated to {0}
+ Click here to view the release notes
+
اختر مدير الملفات
Learn more
@@ -480,6 +489,7 @@
خطأ
An error occurred while opening the folder. {0}
+ An error occurred while opening the URL in the browser. Please check your Default Web Browser configuration in the General section of the settings window
يرجى الانتظار...
diff --git a/Flow.Launcher/Languages/cs.xaml b/Flow.Launcher/Languages/cs.xaml
index 552f1a36d..254298f80 100644
--- a/Flow.Launcher/Languages/cs.xaml
+++ b/Flow.Launcher/Languages/cs.xaml
@@ -136,6 +136,8 @@
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.
+ Show Search Window at Topmost
+ Show search window above other windows
Vyhledat plugin
@@ -370,6 +372,13 @@
Info
Setting Window Font
+
+ See more release notes on GitHub
+ Failed to fetch release notes
+ Please check your network connection or ensure GitHub is accessible
+ Flow Launcher has been updated to {0}
+ Click here to view the release notes
+
Vybrat správce souborů
Learn more
@@ -480,6 +489,7 @@ Pokud před zkratku při zadávání přidáte znak "@", bude odpovíd
Chyba
An error occurred while opening the folder. {0}
+ An error occurred while opening the URL in the browser. Please check your Default Web Browser configuration in the General section of the settings window
Počkejte prosím...
diff --git a/Flow.Launcher/Languages/da.xaml b/Flow.Launcher/Languages/da.xaml
index 7fd6d478a..567532865 100644
--- a/Flow.Launcher/Languages/da.xaml
+++ b/Flow.Launcher/Languages/da.xaml
@@ -94,7 +94,7 @@
Vælg
Skjul Flow Launcher ved opstart
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.
@@ -136,6 +136,8 @@
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.
+ Show Search Window at Topmost
+ Show search window above other windows
Search Plugin
@@ -370,6 +372,13 @@
Info
Setting Window Font
+
+ See more release notes on GitHub
+ Failed to fetch release notes
+ Please check your network connection or ensure GitHub is accessible
+ Flow Launcher has been updated to {0}
+ Click here to view the release notes
+
Select File Manager
Learn more
@@ -480,6 +489,7 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
Error
An error occurred while opening the folder. {0}
+ An error occurred while opening the URL in the browser. Please check your Default Web Browser configuration in the General section of the settings window
Please wait...
diff --git a/Flow.Launcher/Languages/de.xaml b/Flow.Launcher/Languages/de.xaml
index 3c650920f..940881129 100644
--- a/Flow.Launcher/Languages/de.xaml
+++ b/Flow.Launcher/Languages/de.xaml
@@ -136,6 +136,8 @@
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.
+ Show Search Window at Topmost
+ Show search window above other windows
Plug-in suchen
@@ -370,6 +372,13 @@
Info
Setting Window Font
+
+ See more release notes on GitHub
+ Failed to fetch release notes
+ Please check your network connection or ensure GitHub is accessible
+ Flow Launcher has been updated to {0}
+ Click here to view the release notes
+
Dateimanager auswählen
Mehr erfahren
@@ -480,6 +489,7 @@ Wenn Sie bei der Eingabe eines Shortcuts ein '@'-Präfix hinzufügen, stimmt die
Fehler
An error occurred while opening the folder. {0}
+ An error occurred while opening the URL in the browser. Please check your Default Web Browser configuration in the General section of the settings window
Bitte warten Sie ...
diff --git a/Flow.Launcher/Languages/es-419.xaml b/Flow.Launcher/Languages/es-419.xaml
index 5bd77a8dd..40fa76c3d 100644
--- a/Flow.Launcher/Languages/es-419.xaml
+++ b/Flow.Launcher/Languages/es-419.xaml
@@ -136,6 +136,8 @@
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.
+ Show Search Window at Topmost
+ Show search window above other windows
Search Plugin
@@ -370,6 +372,13 @@
Info
Setting Window Font
+
+ See more release notes on GitHub
+ Failed to fetch release notes
+ Please check your network connection or ensure GitHub is accessible
+ Flow Launcher has been updated to {0}
+ Click here to view the release notes
+
Seleccionar Gestor de Archivos
Learn more
@@ -480,6 +489,7 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
Error
An error occurred while opening the folder. {0}
+ An error occurred while opening the URL in the browser. Please check your Default Web Browser configuration in the General section of the settings window
Por favor espere...
diff --git a/Flow.Launcher/Languages/es.xaml b/Flow.Launcher/Languages/es.xaml
index 7324fc01b..1a8b22303 100644
--- a/Flow.Launcher/Languages/es.xaml
+++ b/Flow.Launcher/Languages/es.xaml
@@ -136,6 +136,8 @@
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.
+ Show Search Window at Topmost
+ Show search window above other windows
Buscar complemento
@@ -364,12 +366,19 @@
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.
Abrir carpeta
- Advanced
+ Avanzado
Nivel de registro
Depurar
Información
Configuración de fuente de la ventana
+
+ Ver más notas de la versión en GitHub
+ No se pudo obtener las notas de la versión
+ Por favor, compruebe su conexión de red o asegúrese de que GitHub es accesible
+ Flow Launcher ha sido actualizado a {0}
+ Haga clic aquí para ver las notas de la versión
+
Seleccionar administrador de archivos
Más información
@@ -480,6 +489,7 @@ Si añade un prefijo "@" al introducir un acceso directo, éste coinci
Error
Se ha producido un error al abrir la carpeta. {0}
+ Se ha producido un error al abrir la URL en el navegador. Por favor, compruebe la configuración de su navegador web predeterminado en la sección General de la ventana de configuración
Por favor espere...
diff --git a/Flow.Launcher/Languages/fr.xaml b/Flow.Launcher/Languages/fr.xaml
index 95ad58d6e..e70e75a26 100644
--- a/Flow.Launcher/Languages/fr.xaml
+++ b/Flow.Launcher/Languages/fr.xaml
@@ -136,6 +136,8 @@
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.
+ Afficher la fenêtre de recherche en premier plan
+ Afficher la fenêtre de recherche au-dessus des autres fenêtres
Rechercher des plugins
@@ -369,6 +371,13 @@
Info
Réglage de la police de la fenêtre
+
+ Voir plus de notes de version sur GitHub
+ Impossible de récupérer les notes de version
+ Veuillez vérifier votre connexion réseau ou vous assurer que GitHub est accessible
+ Flow Launcher a été mis à jour à {0}
+ Cliquez ici pour voir les notes de version
+
Sélectionner le gestionnaire de fichiers
En savoir plus
@@ -388,7 +397,7 @@
Navigateur
Nom du navigateur
Chemin du navigateur
- Nouvel onglet
+ Nouvelle fenêtre
Nouvel onglet
Mode privé
@@ -479,6 +488,7 @@ Si vous ajoutez un préfixe "@" lors de la saisie d'un raccourci, celu
Erreur
Une erreur s'est produite lors de l'ouverture du dossier. {0}
+ Une erreur s'est produite lors de l'ouverture de l'URL dans le navigateur. Veuillez vérifier la configuration de votre navigateur Web par défaut dans la section "Général" de la fenêtre des paramètres
Veuillez patienter...
diff --git a/Flow.Launcher/Languages/he.xaml b/Flow.Launcher/Languages/he.xaml
index d1688b647..23f4b7541 100644
--- a/Flow.Launcher/Languages/he.xaml
+++ b/Flow.Launcher/Languages/he.xaml
@@ -135,6 +135,8 @@
Show History Results in Home Page
Maximum History Results Shown in Home Page
ניתן לערוך זאת רק אם התוסף תומך בתכונת הבית ודף הבית מופעל.
+ Show Search Window at Topmost
+ Show search window above other windows
חפש תוסף
@@ -369,6 +371,13 @@
מידע
Setting Window Font
+
+ See more release notes on GitHub
+ Failed to fetch release notes
+ Please check your network connection or ensure GitHub is accessible
+ Flow Launcher has been updated to {0}
+ Click here to view the release notes
+
בחר מנהל קבצים
למד עוד
@@ -479,6 +488,7 @@
שגיאה
אירעה שגיאה בעת פתיחת התיקייה. {0}
+ אירעה שגיאה בעת פתיחת כתובת ה-URL בדפדפן. אנא בדוק את תצורת דפדפן האינטרנט המוגדר כברירת מחדל שלך במקטע הכללי של חלון ההגדרות
אנא המתן...
diff --git a/Flow.Launcher/Languages/it.xaml b/Flow.Launcher/Languages/it.xaml
index 64d9f5abe..f41d960f1 100644
--- a/Flow.Launcher/Languages/it.xaml
+++ b/Flow.Launcher/Languages/it.xaml
@@ -136,6 +136,8 @@
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.
+ Show Search Window at Topmost
+ Show search window above other windows
Plugin di ricerca
@@ -370,6 +372,13 @@
Info
Setting Window Font
+
+ See more release notes on GitHub
+ Failed to fetch release notes
+ Please check your network connection or ensure GitHub is accessible
+ Flow Launcher has been updated to {0}
+ Click here to view the release notes
+
Seleziona Gestore File
Learn more
@@ -480,6 +489,7 @@ Se si aggiunge un prefisso '@' mentre si inserisce una scorciatoia, corrisponde
Error
An error occurred while opening the folder. {0}
+ An error occurred while opening the URL in the browser. Please check your Default Web Browser configuration in the General section of the settings window
Attendere prego...
diff --git a/Flow.Launcher/Languages/ja.xaml b/Flow.Launcher/Languages/ja.xaml
index c2e64ae26..6c1b364f3 100644
--- a/Flow.Launcher/Languages/ja.xaml
+++ b/Flow.Launcher/Languages/ja.xaml
@@ -136,6 +136,8 @@
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.
+ Show Search Window at Topmost
+ Show search window above other windows
Search Plugin
@@ -370,6 +372,13 @@
Info
Setting Window Font
+
+ See more release notes on GitHub
+ Failed to fetch release notes
+ Please check your network connection or ensure GitHub is accessible
+ Flow Launcher has been updated to {0}
+ Click here to view the release notes
+
デフォルトのファイルマネージャー
Learn more
@@ -480,6 +489,7 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
Error
An error occurred while opening the folder. {0}
+ An error occurred while opening the URL in the browser. Please check your Default Web Browser configuration in the General section of the settings window
Please wait...
diff --git a/Flow.Launcher/Languages/ko.xaml b/Flow.Launcher/Languages/ko.xaml
index b78c86a82..1b1eaf4fa 100644
--- a/Flow.Launcher/Languages/ko.xaml
+++ b/Flow.Launcher/Languages/ko.xaml
@@ -127,6 +127,8 @@
히스토리를 홈페이지에 표시
홈페이지에 표시할 최대 히스토리 수
This can only be edited if plugin supports Home feature and Home Page is enabled.
+ Show Search Window at Topmost
+ Show search window above other windows
플러그인 검색
@@ -361,6 +363,13 @@
Info
설정창 글꼴
+
+ See more release notes on GitHub
+ Failed to fetch release notes
+ Please check your network connection or ensure GitHub is accessible
+ Flow Launcher has been updated to {0}
+ Click here to view the release notes
+
파일관리자 선택
더 알아보기
@@ -471,6 +480,7 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
Error
An error occurred while opening the folder. {0}
+ An error occurred while opening the URL in the browser. Please check your Default Web Browser configuration in the General section of the settings window
잠시 기다려주세요...
diff --git a/Flow.Launcher/Languages/nb.xaml b/Flow.Launcher/Languages/nb.xaml
index 9e62ec2cc..07dc84c36 100644
--- a/Flow.Launcher/Languages/nb.xaml
+++ b/Flow.Launcher/Languages/nb.xaml
@@ -136,6 +136,8 @@
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.
+ Show Search Window at Topmost
+ Show search window above other windows
Søk etter programtillegg
@@ -370,6 +372,13 @@
Info
Setting Window Font
+
+ See more release notes on GitHub
+ Failed to fetch release notes
+ Please check your network connection or ensure GitHub is accessible
+ Flow Launcher has been updated to {0}
+ Click here to view the release notes
+
Velg filbehandler
Learn more
@@ -480,6 +489,7 @@ Hvis du legger til et @-prefiks mens du legger inn en snarvei, samsvarer det med
Feil
An error occurred while opening the folder. {0}
+ An error occurred while opening the URL in the browser. Please check your Default Web Browser configuration in the General section of the settings window
Vennligst vent...
diff --git a/Flow.Launcher/Languages/nl.xaml b/Flow.Launcher/Languages/nl.xaml
index 31e6ea768..c74c95010 100644
--- a/Flow.Launcher/Languages/nl.xaml
+++ b/Flow.Launcher/Languages/nl.xaml
@@ -136,6 +136,8 @@
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.
+ Show Search Window at Topmost
+ Show search window above other windows
Plug-ins zoeken
@@ -370,6 +372,13 @@
Info
Setting Window Font
+
+ See more release notes on GitHub
+ Failed to fetch release notes
+ Please check your network connection or ensure GitHub is accessible
+ Flow Launcher has been updated to {0}
+ Click here to view the release notes
+
Bestandsbeheerder selecteren
Learn more
@@ -480,6 +489,7 @@ Als u een '@' voorvoegsel toevoegt tijdens het invoeren van een snelkoppeling, m
Error
An error occurred while opening the folder. {0}
+ An error occurred while opening the URL in the browser. Please check your Default Web Browser configuration in the General section of the settings window
Please wait...
diff --git a/Flow.Launcher/Languages/pl.xaml b/Flow.Launcher/Languages/pl.xaml
index f32a38585..e9ac041f8 100644
--- a/Flow.Launcher/Languages/pl.xaml
+++ b/Flow.Launcher/Languages/pl.xaml
@@ -136,6 +136,8 @@ Kliknij "nie", jeśli jest już zainstalowany. Zostaniesz wtedy popros
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.
+ Show Search Window at Topmost
+ Show search window above other windows
Szukaj wtyczek
@@ -370,6 +372,13 @@ Kliknij "nie", jeśli jest już zainstalowany. Zostaniesz wtedy popros
Info
Ustawienia czcionki okna
+
+ See more release notes on GitHub
+ Failed to fetch release notes
+ Please check your network connection or ensure GitHub is accessible
+ Flow Launcher has been updated to {0}
+ Click here to view the release notes
+
Wybierz menedżer plików
Learn more
@@ -480,6 +489,7 @@ Jeśli dodasz prefiks '@' podczas wprowadzania skrótu, będzie on pasował do d
Błąd
An error occurred while opening the folder. {0}
+ An error occurred while opening the URL in the browser. Please check your Default Web Browser configuration in the General section of the settings window
Proszę czekać...
diff --git a/Flow.Launcher/Languages/pt-br.xaml b/Flow.Launcher/Languages/pt-br.xaml
index bcbfa74af..3e83c1924 100644
--- a/Flow.Launcher/Languages/pt-br.xaml
+++ b/Flow.Launcher/Languages/pt-br.xaml
@@ -136,6 +136,8 @@
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.
+ Show Search Window at Topmost
+ Show search window above other windows
Buscar Plugin
@@ -370,6 +372,13 @@
Info
Setting Window Font
+
+ See more release notes on GitHub
+ Failed to fetch release notes
+ Please check your network connection or ensure GitHub is accessible
+ Flow Launcher has been updated to {0}
+ Click here to view the release notes
+
Selecione o Gerenciador de Arquivos
Learn more
@@ -480,6 +489,7 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
Error
An error occurred while opening the folder. {0}
+ An error occurred while opening the URL in the browser. Please check your Default Web Browser configuration in the General section of the settings window
Por favor, aguarde...
diff --git a/Flow.Launcher/Languages/pt-pt.xaml b/Flow.Launcher/Languages/pt-pt.xaml
index 4eca2c5c6..1bb97f764 100644
--- a/Flow.Launcher/Languages/pt-pt.xaml
+++ b/Flow.Launcher/Languages/pt-pt.xaml
@@ -135,6 +135,8 @@
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.
+ Janela de pesquisa por cima
+ Mostrar caixa de pesquisa por cima das outras janelas
Pesquisar plugins
@@ -366,7 +368,14 @@
Nível de registo
Depuração
Informação
- Setting Window Font
+ Tipo de letra da aplicação
+
+
+ Mostrar notas da versão no GitHub
+ Falha ao obter notas da versão
+ Verifique a sua ligação de rede e confirme se consegue aceder a GitHub
+ Flow Launcher foi atualizado para {0}
+ Clique aqui para ver as notas desta versão
Selecione o gestor de ficheiros
@@ -400,7 +409,7 @@
Palavra-chave atual
Nova palavra-chave
Cancelar
- Feito
+ OK
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.
@@ -478,6 +487,7 @@ Se adicionar o prefixo '@' durante a introdução do atalho, será utilizada qua
Erro
Ocorreu um erro ao abrir a pasta: {0}
+ Ocorreu um erro ao abrir o URL no navegador. Verifique a configuração Navegador web padrão na secção Geral das definições.
Por favor aguarde...
diff --git a/Flow.Launcher/Languages/ru.xaml b/Flow.Launcher/Languages/ru.xaml
index 3a63a4ea4..d52afae1f 100644
--- a/Flow.Launcher/Languages/ru.xaml
+++ b/Flow.Launcher/Languages/ru.xaml
@@ -136,6 +136,8 @@
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.
+ Show Search Window at Topmost
+ Show search window above other windows
Поиск плагина
@@ -370,6 +372,13 @@
Info
Setting Window Font
+
+ See more release notes on GitHub
+ Failed to fetch release notes
+ Please check your network connection or ensure GitHub is accessible
+ Flow Launcher has been updated to {0}
+ Click here to view the release notes
+
Выбор менеджера файлов
Learn more
@@ -480,6 +489,7 @@
Ошибка
An error occurred while opening the folder. {0}
+ An error occurred while opening the URL in the browser. Please check your Default Web Browser configuration in the General section of the settings window
Пожалуйста, подождите...
diff --git a/Flow.Launcher/Languages/sk.xaml b/Flow.Launcher/Languages/sk.xaml
index 3c47d61fd..7aa6ecc65 100644
--- a/Flow.Launcher/Languages/sk.xaml
+++ b/Flow.Launcher/Languages/sk.xaml
@@ -134,8 +134,10 @@
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
+ Maximálny počet zobrazených výsledkov histórie na Domovskej stránke
Úprava je možná len vtedy, ak plugin podporuje funkciu Domovská stránka a Domovská stránka je povolená.
+ Zobraziť vyhľadávacie okno navrchu
+ Zobraziť okno vyhľadávania nad ostatnými oknami
Vyhľadať plugin
@@ -242,7 +244,7 @@
Typ pozadia (backdrop)
Efekt pozadia sa v náhľade nezobrazuje.
Pozadie je podporované od Windows 11 zostava 22000 a novších
- Žiadna
+ Žiadny
Acrylic
Mica
Mica Alt
@@ -370,6 +372,13 @@
Info
Nastavenie písma okna
+
+ Ďalšie poznámky k vydaniu na Githube
+ Nepodarilo sa načítať poznámky k vydaniu
+ Skontrolujte sieťové pripojenie alebo sa uistite, že je Github dostupný
+ Flow Launcher bol aktualizovaný na {0}
+ Na zobrazenie poznámok k vydaniu kliknite sem
+
Vyberte správcu súborov
Viac informácií
@@ -480,6 +489,7 @@ Ak pri zadávaní skratky pred ňu pridáte "@", bude sa zhodovať s
Chyba
Počas otvárania priečinka sa vyskytla chyba. {0}
+ Pri otváraní adresy URL v prehliadači došlo k chybe. Skontrolujte konfiguráciu predvoleného webového prehliadača v nastaveniach Všeobecné
Čakajte, prosím...
diff --git a/Flow.Launcher/Languages/sr.xaml b/Flow.Launcher/Languages/sr.xaml
index 43f316a38..ae7aa7af2 100644
--- a/Flow.Launcher/Languages/sr.xaml
+++ b/Flow.Launcher/Languages/sr.xaml
@@ -136,6 +136,8 @@
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.
+ Show Search Window at Topmost
+ Show search window above other windows
Search Plugin
@@ -370,6 +372,13 @@
Info
Setting Window Font
+
+ See more release notes on GitHub
+ Failed to fetch release notes
+ Please check your network connection or ensure GitHub is accessible
+ Flow Launcher has been updated to {0}
+ Click here to view the release notes
+
Select File Manager
Learn more
@@ -480,6 +489,7 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
Error
An error occurred while opening the folder. {0}
+ An error occurred while opening the URL in the browser. Please check your Default Web Browser configuration in the General section of the settings window
Please wait...
diff --git a/Flow.Launcher/Languages/tr.xaml b/Flow.Launcher/Languages/tr.xaml
index 2f4e4d302..5c118be01 100644
--- a/Flow.Launcher/Languages/tr.xaml
+++ b/Flow.Launcher/Languages/tr.xaml
@@ -106,10 +106,10 @@
Ö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
+ Arama Gecikmesi
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
+ Varsayılan Arama Gecikme Süresi
Wait time before showing results after typing stops. Higher values wait longer. (ms)
Information for Korean IME user
@@ -131,11 +131,13 @@
Aç
Use Previous Korean IME
You can change the Previous Korean IME settings directly from here
- Home Page
+ Ana Sayfa
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.
+ Show Search Window at Topmost
+ Show search window above other windows
Eklenti Ara
@@ -154,11 +156,11 @@
Anahtar kelimeyi değiştir
Plugin search delay time
Change Plugin Search Delay Time
- Advanced Settings:
+ Gelişmiş Ayarlar:
Enabled
- Priority
- Search Delay
- Home Page
+ Öncelik
+ Arama Gecikmesi
+ Ana Sayfa
Mevcut öncelik
Yeni Öncelik
Öncelik
@@ -239,12 +241,12 @@
Özel
Saat
Tarih
- Backdrop Type
+ Arka Plan Türü
The backdrop effect is not applied in the preview.
Backdrop supported starting from Windows 11 build 22000 and above
Hiçbiri
- Acrylic
- Mica
+ Akrilik
+ Mika
Mica Alt
This theme supports two (light/dark) modes.
This theme supports Blur Transparent Background.
@@ -252,7 +254,7 @@
Display placeholder when query is empty
Placeholder text
Change placeholder text. Input empty will use: {0}
- Fixed Window Size
+ Sabit Pencere Boyutu
The window size is not adjustable by dragging.
@@ -356,23 +358,30 @@
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
+ Önbellek Klasörü
+ Önbelleği Temizle
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.
Klasörü Aç
- Advanced
- Log Level
- Debug
- Info
+ Gelişmiş
+ Günlük Düzeyi
+ Hata ayıklama
+ Bilgi
Setting Window Font
+
+ See more release notes on GitHub
+ Sürüm notları alınamadı
+ Please check your network connection or ensure GitHub is accessible
+ Flow Launcher has been updated to {0}
+ Sürüm notlarını görüntülemek için buraya tıklayın
+
Dosya Yöneticisi Seçenekleri
- Learn more
+ Daha fazla bilgi
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.
Dosya Yöneticisi
@@ -409,7 +418,7 @@
This new Action Keyword is the same as old, please choose a different one
Başarılı
Başarıyla tamamlandı
- Failed to copy
+ Kopyalanamadı
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.
@@ -417,7 +426,7 @@
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
+ Ana Sayfa
Enable the plugin home page state if you like to show the plugin results when query is empty.
@@ -448,8 +457,8 @@
Sıfırla
Sil
Güncelle
- Yes
- No
+ Evet
+ Hayır
Arka plan
@@ -472,12 +481,13 @@
2. Copy below exception message
- File Manager Error
+ Dosya Yöneticisi Hatası
The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General.
- Error
- An error occurred while opening the folder. {0}
+ Hata
+ Klasör açılırken bir hata oluştu. {0}
+ An error occurred while opening the URL in the browser. Please check your Default Web Browser configuration in the General section of the settings window
Lütfen bekleyin...
diff --git a/Flow.Launcher/Languages/uk-UA.xaml b/Flow.Launcher/Languages/uk-UA.xaml
index a7dfcda55..a8ee67653 100644
--- a/Flow.Launcher/Languages/uk-UA.xaml
+++ b/Flow.Launcher/Languages/uk-UA.xaml
@@ -136,6 +136,8 @@
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.
+ Show Search Window at Topmost
+ Show search window above other windows
Плагін для пошуку
@@ -370,6 +372,13 @@
Info
Setting Window Font
+
+ See more release notes on GitHub
+ Failed to fetch release notes
+ Please check your network connection or ensure GitHub is accessible
+ Flow Launcher has been updated to {0}
+ Click here to view the release notes
+
Виберіть файловий менеджер
Learn more
@@ -480,6 +489,7 @@
Помилка
An error occurred while opening the folder. {0}
+ An error occurred while opening the URL in the browser. Please check your Default Web Browser configuration in the General section of the settings window
Будь ласка, зачекайте...
diff --git a/Flow.Launcher/Languages/vi.xaml b/Flow.Launcher/Languages/vi.xaml
index b77c6d4e8..a2875f3c0 100644
--- a/Flow.Launcher/Languages/vi.xaml
+++ b/Flow.Launcher/Languages/vi.xaml
@@ -136,6 +136,8 @@
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.
+ Show Search Window at Topmost
+ Show search window above other windows
Plugin tìm kiếm
@@ -372,6 +374,13 @@
Info
Setting Window Font
+
+ See more release notes on GitHub
+ Failed to fetch release notes
+ Please check your network connection or ensure GitHub is accessible
+ Flow Launcher has been updated to {0}
+ Click here to view the release notes
+
Chọn trình quản lý tệp
Learn more
@@ -484,6 +493,7 @@
Lỗi
An error occurred while opening the folder. {0}
+ An error occurred while opening the URL in the browser. Please check your Default Web Browser configuration in the General section of the settings window
Cảnh báo nhỏ...
diff --git a/Flow.Launcher/Languages/zh-cn.xaml b/Flow.Launcher/Languages/zh-cn.xaml
index 95a97d5ed..698eee1e3 100644
--- a/Flow.Launcher/Languages/zh-cn.xaml
+++ b/Flow.Launcher/Languages/zh-cn.xaml
@@ -136,6 +136,8 @@
在主页中显示历史记录
在主页显示的最大历史结果数
这只能在插件支持主页功能和主页启用时进行编辑。
+ Show Search Window at Topmost
+ Show search window above other windows
搜索插件
@@ -239,7 +241,7 @@
自定义
时钟
日期
- 返回类型
+ 背景类型
预览中没有应用背景效果。
自 Windows 11 Build 22000 起支持背景效果
无
@@ -370,6 +372,13 @@
信息
设置窗口字体
+
+ 在 GitHub 上查看更多版本说明
+ 无法获取版本说明
+ 请检查您的网络连接或确认 GitHub 可访问
+ Flow Launcher 已更新到 {0}
+ 单击此处查看版本说明
+
默认文件管理器
了解更多
@@ -480,6 +489,7 @@
错误
打开文件夹时发生错误。{0}
+ 打开浏览器中的 URL 时发生错误。请在设置窗口的常规部分检查您的默认网页浏览器配置
请稍等...
diff --git a/Flow.Launcher/Languages/zh-tw.xaml b/Flow.Launcher/Languages/zh-tw.xaml
index 60531c6aa..0f6ad3f5b 100644
--- a/Flow.Launcher/Languages/zh-tw.xaml
+++ b/Flow.Launcher/Languages/zh-tw.xaml
@@ -136,6 +136,8 @@
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.
+ Show Search Window at Topmost
+ Show search window above other windows
Search Plugin
@@ -370,6 +372,13 @@
Info
Setting Window Font
+
+ See more release notes on GitHub
+ Failed to fetch release notes
+ Please check your network connection or ensure GitHub is accessible
+ Flow Launcher has been updated to {0}
+ Click here to view the release notes
+
選擇檔案管理器
Learn more
@@ -480,6 +489,7 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
Error
An error occurred while opening the folder. {0}
+ An error occurred while opening the URL in the browser. Please check your Default Web Browser configuration in the General section of the settings window
請稍後...
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/ar.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/ar.xaml
index bde48c7d4..29b0d4ed1 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/ar.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/ar.xaml
@@ -25,4 +25,6 @@
محرك المتصفح
إذا كنت لا تستخدم Chrome أو Firefox أو Edge، أو كنت تستخدم نسختهم المحمولة، ستحتاج إلى إضافة دليل بيانات الإشارات المرجعية وتحديد محرك المتصفح الصحيح لجعل هذه الإضافة تعمل.
على سبيل المثال: محرك Brave هو Chromium؛ وموقع بيانات الإشارات المرجعية الافتراضي هو: "%LOCALAPPDATA%\BraveSoftware\Brave-Browser\UserData". بالنسبة لمحرك Firefox، دليل الإشارات المرجعية هو مجلد userdata الذي يحتوي على ملف places.sqlite.
+ Load favicons (can be time consuming during startup)
+
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/cs.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/cs.xaml
index 7511b96f3..45f8d97da 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/cs.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/cs.xaml
@@ -25,4 +25,6 @@
Jádro webového prohlížeče
Pokud nepoužíváte prohlížeč Chrome, Firefox nebo Edge nebo používáte přenosnou verzi prohlížeče Chrome, Firefox nebo Edge, musíte přidat složku záložek a vybrat správné jádro prohlížeče, aby tento doplněk fungoval.
Například: prohlížeč Brave má jádro Chromium; výchozí umístění pro data záložek je: "%LOCALAPPDATA%\BraveSoftware\Brave-Browser\UserData". V případě jádra Firefox je složkou záložek složka userdata, která obsahuje soubor places.sqlite.
+ Load favicons (can be time consuming during startup)
+
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/da.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/da.xaml
index 49c087484..153b05d76 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/da.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/da.xaml
@@ -25,4 +25,6 @@
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.
+ Load favicons (can be time consuming during startup)
+
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/de.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/de.xaml
index 4d1ad4bf1..4a764bbfa 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/de.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/de.xaml
@@ -26,4 +26,6 @@
Wenn Sie nicht Chrome, Firefox oder Edge verwenden oder deren portable Version nutzen, müssen Sie das Lesezeichen-Datenverzeichnis hinzufügen und die richtige Browser-Engine auswählen, damit dieses Plug-in funktioniert.
Zum Beispiel: Die Engine von Brave ist Chromium, und deren Standardspeicherort der Lesezeichen-Daten ist:
%LOCALAPPDATA%\BraveSoftware\Brave-Browser\UserData". Bei der Firefox-Engine ist das Lesezeichenverzeichnis der Ordner userdata, der die Datei places.sqlite enthält.
+ Load favicons (can be time consuming during startup)
+
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/es-419.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/es-419.xaml
index 0f7a95571..28524229b 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/es-419.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/es-419.xaml
@@ -25,4 +25,6 @@
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.
+ Load favicons (can be time consuming during startup)
+
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/es.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/es.xaml
index db87ee281..ba9efd7e0 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/es.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/es.xaml
@@ -25,4 +25,6 @@
Motor del navegador
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.
+ Cargar favicons (puede llevar mucho tiempo durante el arranque)
+
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/fr.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/fr.xaml
index ea0092601..39546c102 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/fr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/fr.xaml
@@ -25,4 +25,6 @@
Navigateur
Si vous n'utilisez pas Chrome, Firefox ou Edge, ou que vous utilisez leur version portable, vous devez ajouter un dossier de favoris et sélectionner le bon navigateur pour que ce plugin fonctionne.
Par exemple : le moteur de Brave est Chromium ; et son emplacement par défaut des favoris est : "%LOCALAPPDATA%\BraveSoftware\Brave-Browser\UserData". Pour le moteur Firefox, le dossier des favoris est le dossier userdata contenant le fichier places.sqlite.
+ Charger les favicons (peut prendre du temps au démarrage)
+
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/he.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/he.xaml
index e524f1172..79490928d 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/he.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/he.xaml
@@ -25,4 +25,6 @@
מנוע דפדפן
אם אינך משתמש ב-Chrome, Firefox או Edge, או שאתה משתמש בגרסה הניידת שלהם, עליך להוסיף את ספריית נתוני הסימניות ולבחור את מנוע הדפדפן המתאים כדי שהתוסף יעבוד.
לדוגמה: המנוע של Brave הוא Chromium, ומיקום ברירת המחדל של נתוני הסימניות שלו הוא: %LOCALAPPDATA%\BraveSoftware\Brave-Browser\UserData. עבור מנוע Firefox, ספריית הסימניות היא תיקיית המשתמש שמכילה את הקובץ places.sqlite.
+ Load favicons (can be time consuming during startup)
+
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/it.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/it.xaml
index 0491ba973..eb13bf852 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/it.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/it.xaml
@@ -25,4 +25,6 @@
Motore di Navigazione
Se non si utilizza Chrome, Firefox o Edge, o si utilizza la loro versione portatile, è necessario aggiungere la cartella dei segnalibri e selezionare il motore di navigazione corretto per far funzionare questo plugin.
Per esempio: il motore di Brave è Chromium, e la sua posizione predefinita dei segnalibri è: "%LOCALAPPDATA%\BraveSoftware\Brave-Browser\UserData". Per il motore di Firefox, la directory dei segnalibri è la cartella dei dati utente che contiene il file places.sqlite.
+ Load favicons (can be time consuming during startup)
+
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/ja.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/ja.xaml
index e553a1b7e..d08d67d98 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/ja.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/ja.xaml
@@ -25,4 +25,6 @@
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.
+ Load favicons (can be time consuming during startup)
+
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/ko.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/ko.xaml
index a374e7fc1..bb7c9fc06 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/ko.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/ko.xaml
@@ -25,4 +25,6 @@
브라우저 엔진
크롬, 파이어폭스 또는 엣지를 사용하지 않거나 이들의 포터블 버전을 사용하고 있다면, 이 플러그인을 작동시키기 위해 북마크 데이터 디렉토리를 추가하고 올바른 브라우저 엔진을 선택해야 합니다.
예를 들어: Brave의 엔진은 Chromium이며, 기본 북마크 데이터 위치는 "%LOCALAPPDATA%\BraveSoftware\Brave-Browser\UserData"입니다. Firefox 엔진의 경우, 북마크 위치는 places.sqlite 파일이 포함된 userdata 폴더입니다.
+ Load favicons (can be time consuming during startup)
+
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/nb.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/nb.xaml
index 273dad465..1c53a49d2 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/nb.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/nb.xaml
@@ -25,4 +25,6 @@
Nettlesermotor
Hvis du ikke bruker Chrome, Firefox eller Edge, eller hvis du bruker den bærbare versjonen, må du legge til bokmerkedatakatalog og velge riktig nettlesermotor for å få dette programtillegget til å fungere.
For eksempel: Brave's motor er Chromium; og standardplasseringen av bokmerker er: "%LOCALAPPDATA%\BraveSoftware\Brave-Browser\UserData". For Firefox-motoren er bokmerkekatalogen brukerdatamappen som inneholder places.sqlite-filen.
+ Load favicons (can be time consuming during startup)
+
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/nl.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/nl.xaml
index 319606d22..407786cdd 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/nl.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/nl.xaml
@@ -25,4 +25,6 @@
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.
+ Load favicons (can be time consuming during startup)
+
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/pl.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/pl.xaml
index f487874ac..2dff7543f 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/pl.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/pl.xaml
@@ -25,4 +25,6 @@
Silnik przeglądarki
Jeśli nie używasz Chrome, Firefox lub Edge, lub używasz ich wersji przenośnej, musisz dodać katalog danych zakładek i wybrać poprawny silnik przeglądarki, aby wtyczka działała.
Na przykład: silnikiem przeglądarki Brave jest Chromium, a domyślna lokalizacja danych zakładek to: "%LOCALAPPDATA%\BraveSoftware\Brave-Browser\UserData". W przypadku silnika Firefoksa, katalog zakładek to folder danych użytkownika zawierający plik places.sqlite.
+ Load favicons (can be time consuming during startup)
+
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/pt-br.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/pt-br.xaml
index d8bb949fd..ce264bc5f 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/pt-br.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/pt-br.xaml
@@ -25,4 +25,6 @@
Motor do Navegador
Se você não estiver usando o Chrome, Firefox ou Edge, ou se estiver usando suas versões portáteis, você precisa adicionar o diretório de dados dos favoritos e selecionar a ferramenta de busca correta para fazer este plugin funcionar.
Por exemplo: O motor do Brave é o Chromium; e seu diretório padrão de favoritos é "%LOCALAPPDATA%\BraveSoftware\Brave-Browser\UserData". Para o motor do Firefox, o diretório de favoritos é a pasta do usuário que contém o arquivo "places.sqlite".
+ Load favicons (can be time consuming during startup)
+
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/pt-pt.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/pt-pt.xaml
index 06af5ea5b..2818a0600 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/pt-pt.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/pt-pt.xaml
@@ -25,4 +25,6 @@
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 navegador Firefox, o diretório de marcadores é a pasta de utilizador que contém o ficheiro places.sqlite.
+ Carregar "favicons" (pode atrasar o carregamento da aplicação)
+
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/ru.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/ru.xaml
index 2ebb286a4..bb8639d97 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/ru.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/ru.xaml
@@ -25,4 +25,6 @@
Движок браузера
Если вы не используете Chrome, Firefox или Edge, или используете их портативную версию, вам необходимо добавить каталог данных закладок и выбрать правильный движок браузера, чтобы этот плагин работал.
Например: Движок Brave - Chromium; и его местоположение данных закладок по умолчанию: «%LOCALAPPDATA%\BraveSoftware\Brave-Browser\UserData». Для движка Firefox каталог закладок находится в папке userdata и содержит файл places.sqlite.
+ Load favicons (can be time consuming during startup)
+
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/sk.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/sk.xaml
index 3c1ce9d22..c7556e877 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/sk.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/sk.xaml
@@ -25,4 +25,6 @@
Jadro prehliadača
Ak nepoužívate prehliadač Chrome, Firefox alebo Edge alebo používate ich prenosnú verziu, musíte pridať priečinok s údajmi o záložkách a vybrať správne jadro prehliadača, aby tento plugin fungoval.
Napríklad: Prehliadač Brave má jadro Chromium; predvolené umiestnenie údajov o záložkách je: "%LOCALAPPDATA%\BraveSoftware\Brave-Browser\UserData". Pre jadro Firefoxu je priečinkom záložiek priečinok userdata, ktorý obsahuje súbor places.sqlite.
+ Načítať favicony (môže trvať dlhšie počas spúšťania)
+
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/sr.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/sr.xaml
index be113c8cf..84173e616 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/sr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/sr.xaml
@@ -25,4 +25,6 @@
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.
+ Load favicons (can be time consuming during startup)
+
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/tr.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/tr.xaml
index 76ab14111..8c4280f63 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/tr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/tr.xaml
@@ -25,4 +25,6 @@
Tarayıcı Motoru
Eğer Chrome, Firefox veya Edge kullanmıyor veya bu tarayıcıların taşınabilir sürümlerini kullanıyorsanız tarayıcı motorunu ve yer imlerinin saklandığı dizini elle girmeniz gerekir.
Örneğin: Brave tarayıcısı Chromium tabanlıdır ve yer imleri varsayılan olarak "%LOCALAPPDATA%\BraveSoftware\Brave-Browser\UserData" klasöründe saklanır. Firefox tabanlı tarayıcılar için bu places.sqlite dosyasının bulunduğu kullanıcı verisi klasörüdür.
+ Load favicons (can be time consuming during startup)
+
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/uk-UA.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/uk-UA.xaml
index 93b20366e..b8fd4fb83 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/uk-UA.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/uk-UA.xaml
@@ -25,4 +25,6 @@
Браузерний рушій
Якщо ви не використовуєте Chrome, Firefox або Edge, або використовуєте їхні портативні версії, вам потрібно додати каталог даних закладок і вибрати правильний рушій браузера, щоб цей плагін працював.
Наприклад: Рушій Brave - Chromium, і за замовчуванням розташування даних закладок: "%LOCALAPPDATA%\BraveSoftware\Brave-Browser\UserData". Для браузера Firefox директорія закладок - це папка userdata, що містить файл places.sqlite.
+ Load favicons (can be time consuming during startup)
+
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/vi.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/vi.xaml
index ddc10950e..662c87d49 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/vi.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/vi.xaml
@@ -25,4 +25,6 @@
Công cụ trình duyệt
Nếu bạn không sử dụng Chrome, Firefox hoặc Edge hoặc bạn đang sử dụng phiên bản di động của chúng, bạn cần thêm thư mục dữ liệu dấu trang và chọn đúng công cụ trình duyệt để plugin này hoạt động.
Ví dụ: Engine của Brave là Chrome; và vị trí dữ liệu dấu trang mặc định của nó là: "%LOCALAPPDATA%\BraveSoftware\Brave-Browser\UserData". Đối với công cụ Firefox, thư mục dấu trang là thư mục dữ liệu người dùng chứa tệp địa điểm.sqlite.
+ Load favicons (can be time consuming during startup)
+
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/zh-cn.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/zh-cn.xaml
index 7b628702d..934544367 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/zh-cn.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/zh-cn.xaml
@@ -25,4 +25,6 @@
浏览器引擎
如果你没有使用 Chrome、 Firefox 或 Edge,或者正在使用它们的绿色版, 那么你需要添加书签数据目录并选择正确的浏览器引擎才能使此插件正常工作。
例如:Brave 浏览器的引擎是 Chromium;其默认书签数据位置是 "%LOCALAPPDATA%\BraveSoftware\Brave-Browser\UserData"。 对于 Firefox 引擎的浏览器,书签目录是 places.sqlite 文件所在的用户数据文件夹。
+ 载入收藏夹图标 (启动时可能十分耗时)
+
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/zh-tw.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/zh-tw.xaml
index 8b21bd58d..7fa50a089 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/zh-tw.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/zh-tw.xaml
@@ -25,4 +25,6 @@
瀏覽器引擎
如果你沒有使用 Chrome、Firefox 或 Edge,或者使用它們的便攜版,你需要新增書籤資料位置並選擇正確的瀏覽器引擎,才能讓這個擴充功能正常運作。
例如:Brave 瀏覽器的引擎是 Chromium;而它的預設書籤資料位置是「%LOCALAPPDATA%\BraveSoftware\Brave-Browser\UserData」。對於 Firefox 瀏覽器引擎,書籤資料位置是包含 places.sqlite 檔案的 userdata 資料夾。
+ Load favicons (can be time consuming during startup)
+
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ar.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ar.xaml
index 28f8557c2..d327dcebb 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ar.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ar.xaml
@@ -3,6 +3,8 @@
يرجى إجراء تحديد أولاً
+ Please select a folder path.
+ Please choose a different name or folder path.
يرجى تحديد رابط المجلد
هل أنت متأكد أنك تريد حذف {0}؟
هل أنت متأكد أنك تريد حذف هذا الملف نهائيًا؟
@@ -25,6 +27,7 @@
إضافة
إعدادات عامة
تخصيص الكلمات المفتاحية للإجراءات
+ Customise Quick Access
روابط الوصول السريع
إعدادات Everything
لوحة المعاينة
@@ -41,6 +44,7 @@
مسار الشل
مسارات مستبعدة من البحث المفهرس
استخدام موقع نتيجة البحث كدليل العمل للتنفيذ
+ Display more information like size and age in tooltips
اضغط Enter لفتح المجلد في مدير الملفات الافتراضي
استخدام البحث المفهرس للبحث في المسار
خيارات الفهرسة
@@ -77,6 +81,9 @@
Ctrl + Enter لفتح الدليل
Ctrl + Enter لفتح المجلد الحاوي
+ {0}{4}Size: {1}{4}Date created: {2}{4}Date modified: {3}
+ Unknown
+ {0}{3}Space free: {1}{3}Total size: {2}
نسخ المسار
@@ -90,6 +97,7 @@
حذف الملف الحالي نهائيًا
حذف المجلد الحالي نهائيًا
المسار:
+ Name:
حذف المحدد
تشغيل كمستخدم مختلف
تشغيل العنصر المحدد باستخدام حساب مستخدم مختلف
@@ -160,6 +168,9 @@
هل ترغب في تمكين البحث في المحتوى لـ Everything؟
قد يكون بطيئًا جدًا بدون فهرسة (المدعومة فقط في Everything v1.5+)
+ Unable to find Everything.exe
+ Failed to install Everything, please install it manually
+
قائمة السياق الأصلية
عرض قائمة السياق الأصلية (تجريبي)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/cs.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/cs.xaml
index 86f0d1170..80e181a8f 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/cs.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/cs.xaml
@@ -3,6 +3,8 @@
Nejprve vyberte položku
+ Please select a folder path.
+ Please choose a different name or folder path.
Vyberte odkaz na složku
Opravdu chcete odstranit {0}?
Opravdu chcete trvale odstranit tento soubor?
@@ -25,6 +27,7 @@
Přidat
Všeobecné nastavení
Upravit aktivační příkaz
+ Customise Quick Access
Odkazy rychlého přístupu
Nastavení Everything
Preview Panel
@@ -41,6 +44,7 @@
Cesta k příkazovému řádku
Vyloučená místa indexování
Použít umístění výsledků vyhledávání jako pracovní adresář spustitelného souboru
+ Display more information like size and age in tooltips
Klepnutím na Enter otevřete složku ve výchozím správci souborů
K vyhledání cesty použijte indexové vyhledávání
Možnosti indexování
@@ -77,6 +81,9 @@
Ctrl + Enter pro otevření adresáře
Ctrl + Enter pro otevření umístění složky
+ {0}{4}Size: {1}{4}Date created: {2}{4}Date modified: {3}
+ Neznámý
+ {0}{3}Space free: {1}{3}Total size: {2}
Kopírovat cestu
@@ -90,6 +97,7 @@
Trvale odstranit aktuální soubor
Trvale smazat aktuální složku
Cesta:
+ Name:
Odstranit vybraný
Spustit jako jiný uživatel
Spustí vybranou položku jako uživatel s jiným účtem
@@ -160,6 +168,9 @@
Chcete povolit vyhledávání obsahu prostřednictvím služby Everything?
Bez indexu (který je podporován pouze ve verzi Everything v1.5+) může být velmi pomalý
+ Unable to find Everything.exe
+ Failed to install Everything, please install it manually
+
Native Context Menu
Display native context menu (experimental)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/da.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/da.xaml
index 003db91d1..7cbe281d8 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/da.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/da.xaml
@@ -3,6 +3,8 @@
Please make a selection first
+ Please select a folder path.
+ Please choose a different name or folder path.
Please select a folder link
Are you sure you want to delete {0}?
Are you sure you want to permanently delete this file?
@@ -25,6 +27,7 @@
Tilføj
General Setting
Customise Action Keywords
+ Customise Quick Access
Quick Access Links
Everything Setting
Preview Panel
@@ -41,6 +44,7 @@
Shell Path
Index Search Excluded Paths
Use search result's location as the working directory of the executable
+ Display more information like size and age in tooltips
Hit Enter to open folder in Default File Manager
Use Index Search For Path Search
Indexing Options
@@ -77,6 +81,9 @@
Ctrl + Enter to open the directory
Ctrl + Enter to open the containing folder
+ {0}{4}Size: {1}{4}Date created: {2}{4}Date modified: {3}
+ Unknown
+ {0}{3}Space free: {1}{3}Total size: {2}
Copy path
@@ -90,6 +97,7 @@
Permanently delete current file
Permanently delete current folder
Path:
+ Name:
Delete the selected
Run as different user
Run the selected using a different user account
@@ -160,6 +168,9 @@
Do you want to enable content search for Everything?
It can be very slow without index (which is only supported in Everything v1.5+)
+ Unable to find Everything.exe
+ Failed to install Everything, please install it manually
+
Native Context Menu
Display native context menu (experimental)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/de.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/de.xaml
index d183d44dd..10700a0ee 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/de.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/de.xaml
@@ -3,6 +3,8 @@
Bitte treffen Sie zuerst eine Auswahl
+ Please select a folder path.
+ Please choose a different name or folder path.
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?
@@ -25,6 +27,7 @@
Hinzufügen
Allgemeine Einstellung
Aktions-Schlüsselwörter individuell anpassen
+ Customise Quick Access
Schnellzugriff-Links
Everyhting-Einstellung
Vorschau-Panel
@@ -41,6 +44,7 @@
Shell-Pfad
Indexsuche ausgeschlossene Pfade
Ort des Suchergebnisses als Arbeitsverzeichnis der ausführbaren Datei verwenden
+ Display more information like size and age in tooltips
Drücken Sie Enter, um Ordner im Default-Dateimanager zu öffnen
Indexsuche für Pfadsuche verwenden
Indexierungsoptionen
@@ -77,6 +81,9 @@
Strg+Enter, um das Verzeichnis zu öffnen
Strg+Enter, um den enthaltenden Ordner zu öffnen
+ {0}{4}Size: {1}{4}Date created: {2}{4}Date modified: {3}
+ Unbekannt
+ {0}{3}Space free: {1}{3}Total size: {2}
Pfad kopieren
@@ -90,6 +97,7 @@
Aktuelle Datei dauerhaft löschen
Aktuellen Ordner dauerhaft löschen
Pfad:
+ Name:
Ausgewähltes löschen
Als anderer Benutzer ausführen
Ausgewähltes unter Verwendung eines anderen Benutzerkontos ausführen
@@ -160,6 +168,9 @@
Möchten Sie die Inhaltssuche für Everything aktivieren?
Es kann sehr langsam sein ohne Index (was nur in Everything v1.5+ unterstützt wird)
+ Unable to find Everything.exe
+ Failed to install Everything, please install it manually
+
Natives Kontextmenü
Natives Kontextmenü anzeigen (experimentell)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/es-419.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/es-419.xaml
index 7f5fb043b..4e372adbe 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/es-419.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/es-419.xaml
@@ -3,6 +3,8 @@
Por favor, seleccione primero
+ Please select a folder path.
+ Please choose a different name or folder path.
Please select a folder link
Are you sure you want to delete {0}?
Are you sure you want to permanently delete this file?
@@ -25,6 +27,7 @@
Añadir
General Setting
Customise Action Keywords
+ Customise Quick Access
Quick Access Links
Everything Setting
Preview Panel
@@ -41,6 +44,7 @@
Shell Path
Index Search Excluded Paths
Usar la ubicación de los resultados de búsqueda como directorio de trabajo ejecutable
+ Display more information like size and age in tooltips
Hit Enter to open folder in Default File Manager
Use Index Search For Path Search
Indexing Options
@@ -77,6 +81,9 @@
Ctrl + Enter to open the directory
Ctrl + Enter to open the containing folder
+ {0}{4}Size: {1}{4}Date created: {2}{4}Date modified: {3}
+ Unknown
+ {0}{3}Space free: {1}{3}Total size: {2}
Copy path
@@ -90,6 +97,7 @@
Permanently delete current file
Permanently delete current folder
Path:
+ Name:
Delete the selected
Run as different user
Run the selected using a different user account
@@ -160,6 +168,9 @@
Do you want to enable content search for Everything?
It can be very slow without index (which is only supported in Everything v1.5+)
+ Unable to find Everything.exe
+ Failed to install Everything, please install it manually
+
Native Context Menu
Display native context menu (experimental)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/es.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/es.xaml
index 33fe8eba8..4f5977fa1 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/es.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/es.xaml
@@ -3,6 +3,8 @@
Por favor haga una selección primero
+ Por favor, seleccione una ruta de carpeta.
+ Por favor, elija un nombre o ruta de carpeta diferente.
Por favor, seleccione un enlace de carpeta
¿Está seguro de que desea eliminar {0}?
¿Está seguro de que desea eliminar permanentemente este archivo?
@@ -25,6 +27,7 @@
Añadir
Configuración general
Personalizar palabras clave de acción
+ Personalizar Acceso Rápido
Enlaces de acceso rápido
Configuración Everything
Panel de vista previa
@@ -41,6 +44,7 @@
Ruta del Shell
Rutas excluídas del índice de búsqueda
Usar la ubicación de los resultados de búsqueda como directorio de trabajo del ejecutable
+ Mostrar más información, como tamaño y antigüedad, en los consejos (tooltips)
Pulsar Entrar para abrir la carpeta en el administrador de archivos predeterminado
Usar búsqueda indexada para buscar rutas
Opciones de indexación
@@ -77,6 +81,9 @@
Ctrl + Entrar para abrir el directorio
Ctrl + Entrar para abrir la carpeta contenedora
+ {0}{4}Tamaño: {1}{4}Fecha de creación: {2}{4}Fecha de modificación: {3}
+ Desconocido
+ {0}{3}Espacio libre: {1}{3}Tamaño total: {2}
Copiar ruta
@@ -90,6 +97,7 @@
Elimina permanentemente el archivo actual
Elimina permanentemente la carpeta actual
Ruta:
+ Nombre:
Elimina el seleccionado
Ejecutar como usuario diferente
Ejecuta la selección usando una cuenta de usuario diferente
@@ -160,6 +168,9 @@
¿Desea activar la búsqueda de contenidos de Everything?
Puede ser muy lento sin índice (solo se admite en Everything v1.5+)
+ No se puede encontrar Everything.exe
+ No se ha podido instalar Everything, por favor, instálelo manualmente
+
Menú contextual nativo
Mostrar menú contextual nativo (experimental)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/fr.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/fr.xaml
index ab5e0d381..726fbe7d7 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/fr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/fr.xaml
@@ -3,6 +3,8 @@
Veuillez d'abord effectuer une sélection
+ Veuillez sélectionner un chemin d'accès au dossier.
+ Veuillez choisir un nom ou un chemin d'accès différent.
Veuillez sélectionner un lien vers un dossier
Êtes-vous sûr de vouloir supprimer {0} ?
Êtes-vous sûr de vouloir supprimer définitivement ce fichier ?
@@ -25,6 +27,7 @@
Ajouter
Paramètres généraux
Personnaliser les mots-clés d'action
+ Personnaliser l'accès rapide
Liens d'accès rapide
Paramètres Everything
Panneau d'aperçu
@@ -41,6 +44,7 @@
Chemin d'accès au Shell
Chemins exclus de la recherche d'index
Utiliser l'emplacement du résultat de la recherche comme répertoire de travail de l'exécutable
+ Afficher plus d'informations comme la taille et l'âge dans les infobulles
Appuyez sur Entrée pour ouvrir le dossier dans le gestionnaire de fichiers par défaut
Utiliser la recherche d'index pour la recherche de chemin d'accès
Options d'indexation
@@ -77,6 +81,9 @@
Ctrl + Entrée pour ouvrir le répertoire
Ctrl + Entrée pour ouvrir le dossier contenant
+ {0}{4} Taille : {1}{4}Date de création : {2}{4}Date de modification : {3}
+ Inconnu
+ {0}{3}Espace libre : {1}{3}Taille totale : {2}
Copier le chemin
@@ -90,6 +97,7 @@
Supprimer définitivement le fichier actuel
Supprimer définitivement le dossier actuel
Chemin :
+ Nom :
Supprimer la sélection
Exécuter en tant qu'utilisateur différent
Exécuter le programme sélectionné en utilisant un autre compte d'utilisateur
@@ -160,6 +168,9 @@
Voulez-vous activer la recherche de contenu pour Everything ?
Il peut être très lent sans index (qui n'est supporté que dans Everything v1.5+).
+ Impossible de trouver Everything.exe
+ Impossible d'installer Everything, veuillez l'installer manuellement
+
Menu contextuel natif
Afficher le menu contextuel natif (expérimental)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/he.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/he.xaml
index 7c1003c2b..6e955848d 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/he.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/he.xaml
@@ -3,6 +3,8 @@
אנא בצע בחירה תחילה
+ אנא בחר נתיב לתיקייה.
+ אנא בחר שם או נתיב תיקייה אחר.
אנא בחר קישור לתיקייה
האם אתה בטוח שברצונך למחוק את {0}?
האם אתה בטוח שברצונך למחוק קובץ זה לצמיתות?
@@ -25,6 +27,7 @@
הוסף
הגדרות כלליות
התאמת מילות פעולה
+ התאמה אישית של גישה מהירה
קישורי גישה מהירה
הגדרות Everything
חלונית תצוגה מקדימה
@@ -41,6 +44,7 @@
נתיב Shell
נתיבים שלא נכללים בחיפוש אינדקס
השתמש במיקום תוצאת החיפוש כספריית העבודה של הקובץ להפעלה
+ Display more information like size and age in tooltips
לחץ Enter כדי לפתוח את התיקייה במנהל הקבצים המוגדר כברירת מחדל
השתמש בחיפוש אינדקס עבור חיפוש נתיבים
אפשרויות אינדקס
@@ -77,6 +81,9 @@
Ctrl + Enter לפתיחת התיקייה
Ctrl + Enter לפתיחת התיקייה המכילה
+ {0}{4}Size: {1}{4}Date created: {2}{4}Date modified: {3}
+ לא ידוע
+ {0}{3}Space free: {1}{3}Total size: {2}
העתק נתיב
@@ -90,6 +97,7 @@
מחק לצמיתות את הקובץ הנוכחי
מחק לצמיתות את התיקייה הנוכחית
נתיב:
+ שם:
מחק את הפריט שנבחר
הפעל כמשתמש אחר
הפעל את הפריט שנבחר באמצעות חשבון משתמש אחר
@@ -160,6 +168,9 @@
האם ברצונך לאפשר חיפוש תוכן עבור Everything?
החיפוש עשוי להיות איטי מאוד ללא אינדקס (שנתמך רק ב-Everything v1.5+)
+ לא ניתן למצוא את Everything.exe
+ נכשל בהתקנת Everything, אנא התקן אותו ידנית
+
תפריט הקשר מקורי
הצג תפריט הקשר מקורי (ניסיוני)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/it.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/it.xaml
index d05ab66db..df756e886 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/it.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/it.xaml
@@ -3,6 +3,8 @@
Effettua prima una selezione
+ Please select a folder path.
+ Please choose a different name or folder path.
Si prega di selezionare un collegamento alla cartella
Sei sicuro di voler eliminare {0}?
Sei sicuro di voler eliminare definitivamente questo file?
@@ -25,6 +27,7 @@
Aggiungi
Impostazione Generale
Personalizza Parola Chiave
+ Customise Quick Access
Collegamenti ad Accesso Rapido
Impostazioni di Everything
Pannello Anteprima
@@ -41,6 +44,7 @@
Percorso Shell
Percorsi Esclusi dall'Indice di Ricerca
Utilizza il percorso ottenuto dalla ricerca come cartella di lavoro
+ Display more information like size and age in tooltips
Premi Invio per aprire la cartella nel gestore file predefinito
Usa Indice di Ricerca per la Ricerca Percorso
Opzioni di Indicizzazione
@@ -77,6 +81,9 @@
Ctrl + Invio per aprire la cartella
Ctrl + Invio per aprire la cartella che lo contiene
+ {0}{4}Size: {1}{4}Date created: {2}{4}Date modified: {3}
+ Unknown
+ {0}{3}Space free: {1}{3}Total size: {2}
Copia percorso
@@ -90,6 +97,7 @@
Elimina permanentemente il file corrente
Elimina definitivamente la cartella corrente
Percorso:
+ Name:
Elimina il selezionato
Esegui come utente differente
Esegui la selezione utilizzando un altro account utente
@@ -160,6 +168,9 @@
Vuoi abilitare la ricerca di contenuti per Everything?
Può essere molto lento senza indice (che è supportato solo in Everything v1.5+)
+ Unable to find Everything.exe
+ Failed to install Everything, please install it manually
+
Menu Contestuale Nativo
Visualizza il menu contestuale nativo (sperimentale)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ja.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ja.xaml
index a0d45be00..3d944a2b8 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ja.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ja.xaml
@@ -3,6 +3,8 @@
Please make a selection first
+ Please select a folder path.
+ Please choose a different name or folder path.
Please select a folder link
Are you sure you want to delete {0}?
Are you sure you want to permanently delete this file?
@@ -25,6 +27,7 @@
追加
一般設定
アクションキーワードのカスタマイズ
+ Customise Quick Access
Quick Access Links
Everything Setting
プレビューパネル
@@ -41,6 +44,7 @@
Shell Path
インデックス検索の除外パス
検索結果の場所を実行ファイルの作業ディレクトリとして使用
+ Display more information like size and age in tooltips
Enterキーで既定のファイルマネージャーでフォルダーを開く
Use Index Search For Path Search
Indexing Options
@@ -77,6 +81,9 @@
Ctrl + Enter to open the directory
Ctrl + Enter to open the containing folder
+ {0}{4}Size: {1}{4}Date created: {2}{4}Date modified: {3}
+ Unknown
+ {0}{3}Space free: {1}{3}Total size: {2}
パスをコピー
@@ -90,6 +97,7 @@
現在のファイルを完全に削除
現在のフォルダーを完全に削除
Path:
+ Name:
Delete the selected
Run as different user
Run the selected using a different user account
@@ -160,6 +168,9 @@
Do you want to enable content search for Everything?
It can be very slow without index (which is only supported in Everything v1.5+)
+ Unable to find Everything.exe
+ Failed to install Everything, please install it manually
+
Native Context Menu
Display native context menu (experimental)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ko.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ko.xaml
index 82c3ef4e8..27e4aa76a 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ko.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ko.xaml
@@ -3,6 +3,8 @@
항목을 먼저 선택하세요
+ Please select a folder path.
+ Please choose a different name or folder path.
폴더 링크를 선택하세요
{0} - 삭제하시겠습니까?
이 파일을 영구적으로 삭제하시겠습니까?
@@ -25,6 +27,7 @@
추가
일반 설정
사용자 지정 액션 키워드
+ Customise Quick Access
빠른 접근 항목
Everything 설정
미리보기 패널
@@ -41,6 +44,7 @@
쉘 경로
색인 제외 경로
검색 결과위치를 실행 가능한 작업 디렉토리(Working Directory)로 사용
+ Display more information like size and age in tooltips
Enter 키를 눌렀을 때 기본 파일 관리자에서 폴더 열기
Use Index Search For Path Search
색인 옵션
@@ -77,6 +81,9 @@
Ctrl + Enter으로 폴더 열기
Ctrl + Enter으로 포함된 폴더 열기
+ {0}{4}Size: {1}{4}Date created: {2}{4}Date modified: {3}
+ Unknown
+ {0}{3}Space free: {1}{3}Total size: {2}
경로 복사
@@ -90,6 +97,7 @@
이 파일을 영구적으로 삭제
이 폴더를 영구적으로 삭제
경로:
+ Name:
선택 항목을 삭제
다른 유저 권한으로 실행
선택한 사용자 계정으로 실행
@@ -160,6 +168,9 @@
Eveyrhing으로 내용 검색을 활성화하시겠습니까?
인덱스가 없으면 매우 느릴 수 있습니다.(Everything v1.5+에서만 지원)
+ Unable to find Everything.exe
+ Failed to install Everything, please install it manually
+
Native Context Menu
Display native context menu (experimental)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/nb.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/nb.xaml
index f8c0374f3..e5ef88959 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/nb.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/nb.xaml
@@ -3,6 +3,8 @@
Vennligst gjør et valg først
+ Please select a folder path.
+ Please choose a different name or folder path.
Velg en mappekobling
Er du sikker på at du ønsker å slette {0}?
Er du sikker på at du vil slette denne filen permanent?
@@ -25,6 +27,7 @@
Legg til
Generell innstilling
Tilpass handlingsnøkkelord
+ Customise Quick Access
Koblinger for hurtigtilgang
Everything-innstilling
Forhåndsvisningspanel
@@ -41,6 +44,7 @@
Skall-sti
Søk i indekser ekskluderte baner
Bruk søkeresultatets plassering som arbeidskatalogen til den kjørbare filen
+ Display more information like size and age in tooltips
Trykk Enter for å åpne mappen i standard filbehandler
Bruk indekssøk for banesøk
Alternativer for indeksering
@@ -77,6 +81,9 @@
Ctrl + Enter for å åpne katalogen
Ctrl + Enter for å åpne mappen som inneholder
+ {0}{4}Size: {1}{4}Date created: {2}{4}Date modified: {3}
+ Ukjent
+ {0}{3}Space free: {1}{3}Total size: {2}
Kopier sti
@@ -90,6 +97,7 @@
Slett gjeldende fil permanent
Slett gjeldende mappe permanent
Sti:
+ Name:
Slett valgte
Kjør som annen bruker
Kjør valgte med en annen brukerkonto
@@ -160,6 +168,9 @@
Vil du aktivere innholdssøk for Everything?
Det kan være veldig tregt uten indeks (som bare støttes i Everything v1.5+)
+ Unable to find Everything.exe
+ Failed to install Everything, please install it manually
+
Opprinnelig hurtigmeny
Vis opprinnelig hurtigmeny (eksperimentell)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/nl.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/nl.xaml
index 23fdcc214..d8178a1f3 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/nl.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/nl.xaml
@@ -3,6 +3,8 @@
Please make a selection first
+ Please select a folder path.
+ Please choose a different name or folder path.
Please select a folder link
Are you sure you want to delete {0}?
Are you sure you want to permanently delete this file?
@@ -25,6 +27,7 @@
Toevoegen
General Setting
Customise Action Keywords
+ Customise Quick Access
Quick Access Links
Everything Setting
Voorbeeld Paneel
@@ -41,6 +44,7 @@
Shell Path
Index Search Excluded Paths
Use search result's location as the working directory of the executable
+ Display more information like size and age in tooltips
Hit Enter to open folder in Default File Manager
Use Index Search For Path Search
Indexing Options
@@ -77,6 +81,9 @@
Ctrl + Enter to open the directory
Ctrl + Enter to open the containing folder
+ {0}{4}Size: {1}{4}Date created: {2}{4}Date modified: {3}
+ Unknown
+ {0}{3}Space free: {1}{3}Total size: {2}
Copy path
@@ -90,6 +97,7 @@
Permanently delete current file
Permanently delete current folder
Path:
+ Name:
Delete the selected
Run as different user
Run the selected using a different user account
@@ -160,6 +168,9 @@
Do you want to enable content search for Everything?
It can be very slow without index (which is only supported in Everything v1.5+)
+ Unable to find Everything.exe
+ Failed to install Everything, please install it manually
+
Native Context Menu
Display native context menu (experimental)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pl.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pl.xaml
index 5b7afac8e..5a29fd9ab 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pl.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pl.xaml
@@ -3,6 +3,8 @@
Pierw dokonaj wyboru
+ Please select a folder path.
+ Please choose a different name or folder path.
Musisz wybrać któryś folder z listy
Czy jesteś pewien że chcesz usunąć {0}?
Jesteś pewny, że chcesz usunąć ten plik trwale?
@@ -25,6 +27,7 @@
Dodaj
Ustawienia ogólne
Zmień słowa kluczowe akcji
+ Customise Quick Access
Linki szybkiego dostępu
Ustawienia Everything
Panel podglądu
@@ -41,6 +44,7 @@
Ścieżka powłoki
Wykluczone ścieżki indeksu
Użyj lokalizacji wyników wyszukiwania jako katalogu roboczego pliku wykonywalnego
+ Display more information like size and age in tooltips
Naciśnij Enter, aby otworzyć folder w domyślnym menedżerze plików
Użyj wyszukiwania indeksowego do przeszukiwania ścieżek
Opcje indeksowania
@@ -77,6 +81,9 @@
Ctrl + Enter, aby otworzyć folder
Ctrl + Enter, aby otworzyć folder zawierający
+ {0}{4}Size: {1}{4}Date created: {2}{4}Date modified: {3}
+ Nieznane
+ {0}{3}Space free: {1}{3}Total size: {2}
Skopiuj Ścieżkę
@@ -90,6 +97,7 @@
Trwale usuń bieżący plik
Trwale usuń bieżący folder
Ścieżka:
+ Name:
Usuń zaznaczone
Uruchom jako inny użytkownik
Uruchom wybrane używając innego konta użytkownika
@@ -160,6 +168,9 @@
Czy chcesz włączyć wyszukiwanie zawartości dla programu Everything?
Może działać bardzo wolno bez indeksu (który jest obsługiwany tylko w Everything w wersji 1.5 i nowszych)
+ Unable to find Everything.exe
+ Failed to install Everything, please install it manually
+
Natywne menu kontekstowe
Wyświetl natywne menu kontekstowe (eksperymentalne)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-br.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-br.xaml
index 50aba68b8..5785a5616 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-br.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-br.xaml
@@ -3,6 +3,8 @@
Please make a selection first
+ Please select a folder path.
+ Please choose a different name or folder path.
Please select a folder link
Are you sure you want to delete {0}?
Are you sure you want to permanently delete this file?
@@ -25,6 +27,7 @@
Adicionar
General Setting
Customise Action Keywords
+ Customise Quick Access
Links de Acesso Rápido
Everything Setting
Preview Panel
@@ -41,6 +44,7 @@
Shell Path
Index Search Excluded Paths
Use search result's location as the working directory of the executable
+ Display more information like size and age in tooltips
Hit Enter to open folder in Default File Manager
Use Index Search For Path Search
Indexing Options
@@ -77,6 +81,9 @@
Ctrl + Enter to open the directory
Ctrl + Enter to open the containing folder
+ {0}{4}Size: {1}{4}Date created: {2}{4}Date modified: {3}
+ Unknown
+ {0}{3}Space free: {1}{3}Total size: {2}
Copy path
@@ -90,6 +97,7 @@
Permanently delete current file
Permanently delete current folder
Caminho:
+ Name:
Delete the selected
Run as different user
Run the selected using a different user account
@@ -160,6 +168,9 @@
Do you want to enable content search for Everything?
It can be very slow without index (which is only supported in Everything v1.5+)
+ Unable to find Everything.exe
+ Failed to install Everything, please install it manually
+
Native Context Menu
Display native context menu (experimental)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-pt.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-pt.xaml
index 7112f118d..5db8251e2 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-pt.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-pt.xaml
@@ -3,6 +3,8 @@
Tem que efetuar uma seleção
+ Selecione o caminho da pasta.
+ Por favor, escolha um nome ou caminho diferente.
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?
@@ -25,6 +27,7 @@
Adicionar
Definições gerais
Personalizar palavras-chave
+ Personalizar acesso rápido
Ligações de acesso rápido
Definições Everything
Painel de pré-visualização
@@ -41,6 +44,7 @@
Caminho da consola
Caminhos excluídos do índice de pesquisa
Utilizar localização do resultado da pesquisa como pasta de trabalho do executável
+ Mostrar mais informações nas dicas (ex.: tamanho e antiguidade)
Toque Enter para abrir a pasta no gestor de ficheiros
Utilizar índice de pesquisa para o caminho
Opções de indexação
@@ -50,7 +54,7 @@
Pesquisa no índice:
Acesso rápido:
Palavra-chave atual
- Feito
+ OK
Ativo
Se desativar a opção, Flow Launcher não irá executar esta opção de pesquisa e utilizará '*' para libertar a palavra-chave
Everything
@@ -77,6 +81,9 @@
Ctrl+Enter para abrir a pasta
Ctrl+Enter para abrir a pasta de destino
+ {0}{4}Tamanho: {1}{4}Data de criação: {2}{4}Data de modificação: {3}
+ Desconhecido
+ {0}{3}Espaço livre: {1}{3}Tamanho total: {2}
Copiar caminho
@@ -90,6 +97,7 @@
Eliminar permanentemente o ficheiro atual
Eliminar permanentemente a pasta atual
Caminho:
+ Nome:
Eliminar seleção
Executar com outro utilizador
Executar ações com uma conta de utilizador diferente
@@ -160,6 +168,9 @@
Deseja ativar a pesquisa de conteúdo através de Everything?
Pode ser muito lento sem índice (que apenas existe em Everything v1.5+)
+ Não foi possível encontrar Everything.exe
+ Não foi possível instalar Everything. Experimente instalar manualmente.
+
Menu de contexto nativo
Mostrar menu de contexto nativo (experimental)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ru.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ru.xaml
index ae5211b73..35bd1d87d 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ru.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ru.xaml
@@ -3,6 +3,8 @@
Сначала отметьте что-нибудь
+ Please select a folder path.
+ Please choose a different name or folder path.
Пожалуйста, выберите ссылку на папку
Вы уверены, что хотите удалить {0}?
Вы действительно хотите безвозвратно удалить этот файл?
@@ -25,6 +27,7 @@
Добавить
General Setting
Customise Action Keywords
+ Customise Quick Access
Quick Access Links
Everything Setting
Preview Panel
@@ -41,6 +44,7 @@
Shell Path
Index Search Excluded Paths
Use search result's location as the working directory of the executable
+ Display more information like size and age in tooltips
Hit Enter to open folder in Default File Manager
Use Index Search For Path Search
Indexing Options
@@ -77,6 +81,9 @@
Ctrl + Enter to open the directory
Ctrl + Enter to open the containing folder
+ {0}{4}Size: {1}{4}Date created: {2}{4}Date modified: {3}
+ Unknown
+ {0}{3}Space free: {1}{3}Total size: {2}
Скопировать путь
@@ -90,6 +97,7 @@
Permanently delete current file
Permanently delete current folder
Путь:
+ Name:
Delete the selected
Запустить от имени другого пользователя
Run the selected using a different user account
@@ -160,6 +168,9 @@
Do you want to enable content search for Everything?
It can be very slow without index (which is only supported in Everything v1.5+)
+ Unable to find Everything.exe
+ Failed to install Everything, please install it manually
+
Native Context Menu
Display native context menu (experimental)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/sk.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/sk.xaml
index 0bfb3d024..1323d6ae0 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/sk.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/sk.xaml
@@ -3,6 +3,8 @@
Najprv vyberte položku
+ Vyberte cestu k priečinku.
+ Vyberte iný názov alebo cestu k priečinku.
Vyberte odkaz na priečinok
Naozaj chcete odstrániť {0}?
Naozaj chcete natrvalo odstrániť tento súbor?
@@ -25,6 +27,7 @@
Pridať
Všeobecné nastavenia
Upraviť aktivačný príkaz
+ Prispôsobenie Rýchleho prístupu
Odkazy Rýchleho prístupu
Nastavenia Everything
Panel náhľadu
@@ -41,6 +44,7 @@
Cesta k príkazovému riadku
Vylúčené umiestnenia indexovania
Použiť umiestnenie výsledku vyhľadávania ako pracovný priečinok spustiteľného súboru
+ Zobraziť viac informácií v popise ako veľkosť a dátumy
Stlačením klávesu Enter otvoriť priečinok v predvolenom správcovi súborov
Na vyhľadanie cesty použiť vyhľadávanie v indexe
Možnosti indexovania
@@ -77,6 +81,9 @@
Ctrl + Enter na otvorenie priečinka
Ctrl + Enter na otvorenie umiestnenia priečinka
+ {0}{4}Veľkosť: {1}{4}Dátum vytvorenia: {2}{4}Dátum úpravy: {3}
+ Neznáma
+ {0}{3}Voľné miesto: {1}{3}Celková veľkosť: {2}
Kopírovať cestu
@@ -90,6 +97,7 @@
Natrvalo odstrániť aktuálny súbor
Natrvalo odstrániť aktuálny priečinok
Cesta:
+ Názov:
Odstrániť vybraný
Spustiť ako iný používateľ
Spustí vybranú položku ako používateľ s iným kontom
@@ -160,6 +168,9 @@
Chcete povoliť vyhľadávanie obsahu cez Everything?
Bez indexu (ktorý je podporovaný len v Everything v1.5+) to môže byť veľmi pomalé
+ Nedá sa nájsť Everything.exe
+ Nepodarilo sa nainštalovať Everything, nainštalujte ho manuálne
+
Natívna kontextová ponuka
Zobraziť natívnu kontextovú ponuku (experimentálne)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/sr.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/sr.xaml
index 9e1a91d0c..6af550884 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/sr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/sr.xaml
@@ -3,6 +3,8 @@
Please make a selection first
+ Please select a folder path.
+ Please choose a different name or folder path.
Please select a folder link
Are you sure you want to delete {0}?
Are you sure you want to permanently delete this file?
@@ -25,6 +27,7 @@
Dodaj
General Setting
Customise Action Keywords
+ Customise Quick Access
Quick Access Links
Everything Setting
Preview Panel
@@ -41,6 +44,7 @@
Shell Path
Index Search Excluded Paths
Use search result's location as the working directory of the executable
+ Display more information like size and age in tooltips
Hit Enter to open folder in Default File Manager
Use Index Search For Path Search
Indexing Options
@@ -77,6 +81,9 @@
Ctrl + Enter to open the directory
Ctrl + Enter to open the containing folder
+ {0}{4}Size: {1}{4}Date created: {2}{4}Date modified: {3}
+ Unknown
+ {0}{3}Space free: {1}{3}Total size: {2}
Copy path
@@ -90,6 +97,7 @@
Permanently delete current file
Permanently delete current folder
Path:
+ Name:
Delete the selected
Run as different user
Run the selected using a different user account
@@ -160,6 +168,9 @@
Do you want to enable content search for Everything?
It can be very slow without index (which is only supported in Everything v1.5+)
+ Unable to find Everything.exe
+ Failed to install Everything, please install it manually
+
Native Context Menu
Display native context menu (experimental)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/tr.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/tr.xaml
index a61ff488a..44674952b 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/tr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/tr.xaml
@@ -3,6 +3,8 @@
Please make a selection first
+ Please select a folder path.
+ Please choose a different name or folder path.
Lütfen bir klasör bağlantısı seçin
{0} bağlantısını silmek istediğinize emin misiniz?
Bu dosyayı kalıcı olarak silmek istediğinizden emin misiniz?
@@ -25,6 +27,7 @@
Ekle
Genel Ayarlar
Anahtar Kelimeler
+ Customise Quick Access
Quick Access Links
Everything Ayarları
Önizleme Paneli
@@ -41,6 +44,7 @@
Komut İstemi
Hariç Tutulan Dizinler
Programın çalışma klasörü olarak sonuç klasörünü kullan
+ Display more information like size and age in tooltips
Hit Enter to open folder in Default File Manager
Use Index Search For Path Search
Indexing Options
@@ -77,6 +81,9 @@
Dizini açmak içi Ctrl + Enter
Dosya konumunu açmak için Ctrl + Enter
+ {0}{4}Size: {1}{4}Date created: {2}{4}Date modified: {3}
+ Unknown
+ {0}{3}Space free: {1}{3}Total size: {2}
Yolu kopyala
@@ -90,6 +97,7 @@
Mevcut dosyayı kalıcı olarak sil
Mevcut klasörü kalıcı olarak sil
Yol:
+ Name:
Seçileni sil
Başka bir kullanıcı olarak çalıştır
Run the selected using a different user account
@@ -160,6 +168,9 @@
Do you want to enable content search for Everything?
It can be very slow without index (which is only supported in Everything v1.5+)
+ Unable to find Everything.exe
+ Failed to install Everything, please install it manually
+
Native Context Menu
Display native context menu (experimental)
@@ -167,10 +178,10 @@
Below you can specify items you want to exclude from context menu, they can be partial (e.g. 'pen wit') or complete ('Open with').
- Today
- {0} days ago
- 1 month ago
- {0} months ago
- 1 year ago
- {0} years ago
+ Bugün
+ {0} gün önce
+ 1 ay önce
+ {0} ay önce
+ 1 yıl önce
+ {0} yıl önce
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/uk-UA.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/uk-UA.xaml
index 885d5dd9f..b203687e9 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/uk-UA.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/uk-UA.xaml
@@ -3,6 +3,8 @@
Будь ласка, спочатку зробіть вибір
+ Please select a folder path.
+ Please choose a different name or folder path.
Будь ласка, оберіть посилання на теку
Ви впевнені, що хочете видалити {0}?
Ви впевнені, що хочете назавжди видалити цей файл?
@@ -25,6 +27,7 @@
Додати
Загальні налаштування
Налаштувати ключові слова дії
+ Customise Quick Access
Посилання швидкого доступу
Налаштування Everything
Панель поперегляду
@@ -41,6 +44,7 @@
Шлях до оболонки Shell
Виключені шляхи індексного пошуку
Використовувати розташування результату пошуку як робочу директорію виконуваного файлу
+ Display more information like size and age in tooltips
Натисніть Enter, щоб відкрити папку у файловому менеджері за замовчуванням
Використовуйте індексний пошук для пошуку шляху
Параметри індексації
@@ -77,6 +81,9 @@
Ctrl + Enter, щоб відкрити каталог
Ctrl + Enter, щоб відкрити відповідну папку
+ {0}{4}Size: {1}{4}Date created: {2}{4}Date modified: {3}
+ Невідомо
+ {0}{3}Space free: {1}{3}Total size: {2}
Копіювати шлях
@@ -90,6 +97,7 @@
Безповоротно видалити поточний файл
Назавжди видалити поточну папку
Шлях:
+ Name:
Видалити вибране
Запустити від імені іншого користувача
Запустити вибране під обліковим записом іншого користувача
@@ -160,6 +168,9 @@
Бажаєте увімкнути пошук контенту для Everything?
Без індексу (який підтримується лише у версії Everything v1.5+) воно може працювати дуже повільно
+ Unable to find Everything.exe
+ Failed to install Everything, please install it manually
+
Рідне контекстне меню
Відображати рідне контекстне меню (експериментально)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/vi.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/vi.xaml
index bcc094007..f41276a67 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/vi.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/vi.xaml
@@ -3,6 +3,8 @@
Vui lòng lựa chọn trước
+ Please select a folder path.
+ Please choose a different name or folder path.
Hãy chọn một thư mục.
Bạn có chắc chắn muốn xóa {0} không?
Bạn có chắc là muốn xóa vĩnh viễn các ảnh này?
@@ -25,6 +27,7 @@
Thêm
Cài đặt chung
Tùy chỉnh từ khóa hành động
+ Customise Quick Access
Liên kết truy cập nhanh
Cài đặt mọi thứ
Bảng xem trước
@@ -41,6 +44,7 @@
Đường dẫn Shell
Đường dẫn bị loại trừ tìm kiếm chỉ mục
Sử dụng vị trí của kết quả tìm kiếm làm thư mục làm việc của tệp thực thi
+ Display more information like size and age in tooltips
Chạy với tư cách quản trị viên / mở thư mục trong trình quản lý tệp tiêu chuẩn
Sử dụng Tìm kiếm Chỉ mục để Tìm kiếm Đường dẫn
Tùy chọn lập chỉ mục
@@ -77,6 +81,9 @@
Ctrl + Enter để mở thư mục
Ctrl + Enter để mở thư mục chứa
+ {0}{4}Size: {1}{4}Date created: {2}{4}Date modified: {3}
+ Unknown
+ {0}{3}Space free: {1}{3}Total size: {2}
Copy đường dẫn
@@ -90,6 +97,7 @@
Permanently delete current file
Permanently delete current folder
Đường dẫn:
+ Name:
Xóa đã chọn
Xóa lựa chọn đã chọn
Chạy phần đã chọn bằng tài khoản người dùng khác
@@ -160,6 +168,9 @@
Do you want to enable content search for Everything?
It can be very slow without index (which is only supported in Everything v1.5+)
+ Unable to find Everything.exe
+ Failed to install Everything, please install it manually
+
Native Context Menu
Display native context menu (experimental)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/zh-cn.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/zh-cn.xaml
index fc76857bd..9bce72062 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/zh-cn.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/zh-cn.xaml
@@ -3,6 +3,8 @@
请先进行选择
+ 请选择一个文件夹路径。
+ 请选择不同的名称或文件夹路径。
请选择一个文件夹链接
您确定要删除 {0} 吗?
您确定要永久删除此文件吗?
@@ -25,6 +27,7 @@
添加
通用设置
自定义动作关键字
+ 自定义快速访问
快速访问链接
Everything 设置
预览面板
@@ -41,6 +44,7 @@
Shell 路径
索引搜索排除的路径
使用搜索结果的位置作为应用程序的工作目录
+ 在提示框中显示更多信息,例如大小和年龄
点击回车在默认文件管理器中打开文件夹
使用索引进行路径搜索
索引选项
@@ -77,6 +81,9 @@
Ctrl + Enter 以打开目录
Ctrl + Enter 以打开所在的文件夹
+ {0}{4}大小:{1}{4}创建日期:{2}{4}修改日期:{3}
+ 未知
+ {0}{3}空闲空间:{1}{3}总空间:{2}
复制路径
@@ -90,6 +97,7 @@
永久删除当前文件
永久删除当前文件夹
路径:
+ 名称:
删除所选内容
以其他用户身份运行
使用其他用户帐户运行所选内容
@@ -160,6 +168,9 @@
您想要启用 Everything 的内容搜索功能吗?
如果没有索引,它可能会非常慢(索引仅在 Everything v1.5+ 中支持)
+ 找不到 Everything.exe
+ 安装 Everything 失败,请手动安装
+
本机上下文菜单
显示本机上下文菜单(实验性)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/zh-tw.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/zh-tw.xaml
index dc75bc3bd..931c9de29 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/zh-tw.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/zh-tw.xaml
@@ -3,6 +3,8 @@
Please make a selection first
+ Please select a folder path.
+ Please choose a different name or folder path.
請選擇一個資料夾
你確認要刪除{0}嗎?
Are you sure you want to permanently delete this file?
@@ -25,6 +27,7 @@
新增
General Setting
Customise Action Keywords
+ Customise Quick Access
快速訪問連結
Everything Setting
Preview Panel
@@ -41,6 +44,7 @@
Shell Path
Index Search Excluded Paths
使用程式所在目錄作為工作目錄
+ Display more information like size and age in tooltips
Hit Enter to open folder in Default File Manager
Use Index Search For Path Search
索引選項
@@ -77,6 +81,9 @@
Ctrl + Enter 以開啟該目錄。
Ctrl + Enter to open the containing folder
+ {0}{4}Size: {1}{4}Date created: {2}{4}Date modified: {3}
+ Unknown
+ {0}{3}Space free: {1}{3}Total size: {2}
複製路徑
@@ -90,6 +97,7 @@
Permanently delete current file
Permanently delete current folder
路徑:
+ Name:
刪除所選內容
Run as different user
Run the selected using a different user account
@@ -160,6 +168,9 @@
Do you want to enable content search for Everything?
It can be very slow without index (which is only supported in Everything v1.5+)
+ Unable to find Everything.exe
+ Failed to install Everything, please install it manually
+
Native Context Menu
Display native context menu (experimental)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/tr.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/tr.xaml
index 616ce779b..14f2e1309 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/tr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/tr.xaml
@@ -2,9 +2,9 @@
- Downloading plugin
+ Eklenti indiriliyor
Successfully downloaded
- Error: Unable to download the plugin
+ Hata: Eklenti indirilemiyor
{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.
@@ -22,14 +22,14 @@
Error occurred while trying to install {0}
Error uninstalling plugin
No update available
- All plugins are up to date
+ Tüm eklentiler güncel
{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
+ Tüm eklentileri güncelle
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?
@@ -47,7 +47,7 @@
Plugins Manager
Management of installing, uninstalling or updating Flow Launcher plugins
- Unknown Author
+ Bilinmeyen Yazar
Open website
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/tr.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/tr.xaml
index 126613065..e75dd0fc9 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/tr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/tr.xaml
@@ -2,33 +2,33 @@
- Reset Default
+ Varsayılana Sıfırla
Sil
Düzenle
Ekle
- Name
+ Ad
Etkin
Enabled
Disable
- Status
+ Durum
Enabled
Disabled
Konum
- All Programs
+ Tüm Programlar
File Type
Yeniden İndeksle
İndeksleniyor
Index Sources
- Options
- UWP Apps
+ Seçenekler
+ UWP Uygulamaları
When enabled, Flow will load UWP Applications
- Start Menu
+ Başlat Menüsü
When enabled, Flow will load programs from the start menu
Registry
When enabled, Flow will load programs from the registry
- PATH
+ YOL
When enabled, Flow will load programs from the PATH environment variable
- Hide app path
+ Uygulama yolunu gizle
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
@@ -60,7 +60,7 @@
Protocols can't be empty
İndekslenecek Uzantılar
- URL Protocols
+ URL Protokolleri
Steam Games
Epic Games
Http/Https
@@ -75,8 +75,8 @@
Run As Different User
Yönetici Olarak Çalıştır
- Open containing folder
- Hide
+ İçeren klasörü aç
+ Gizle
Open target folder
Program
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/tr.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/tr.xaml
index aaad035a0..b37070d93 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/tr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/tr.xaml
@@ -3,10 +3,10 @@
Search Source Setting
Open search in:
- New Window
- New Tab
+ Yeni Pencere
+ Yeni Sekme
Set browser from path:
- Choose
+ Seç
Sil
Düzenle
Ekle
@@ -34,7 +34,7 @@
Başlık
- Status
+ Durum
Simge Seç
Simge
İptal
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 39062bbb8..5b0a57759 100644
--- a/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.pt-PT.resx
+++ b/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.pt-PT.resx
@@ -2016,7 +2016,7 @@
Agrupar janelas semelhantes na barra de tarefas
- Alterar configurações do Windows SideShow
+ Alterar definições do Windows SideShow
Usar descrição de áudio para vídeos
@@ -2176,7 +2176,7 @@
Alterar configurações avançadas de gerenciamento de cores para telas, scanners e impressoras
- Permitir que o Windows sugira Facilidade de Acesso
+ Permitir que o Windows sugira a Facilidade de acesso
Limpar espaço em disco excluindo arquivos desnecessários
@@ -2332,7 +2332,7 @@
Move the pointer with the keypad using MouseKeys
- Change Windows SideShow-compatible device settings
+ Alterar definições dos dispositivos compatíveis com SideShow
Adjust commonly used mobility settings
From 74d54990c913cb6ebfaf07cec97fa1128a09812b Mon Sep 17 00:00:00 2001
From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Fri, 13 Jun 2025 00:21:49 +0800
Subject: [PATCH 1533/1697] Delete
Flow.Launcher/Properties/Resources.fr-FR.resx
---
Flow.Launcher/Properties/Resources.fr-FR.resx | 130 ------------------
1 file changed, 130 deletions(-)
delete mode 100644 Flow.Launcher/Properties/Resources.fr-FR.resx
diff --git a/Flow.Launcher/Properties/Resources.fr-FR.resx b/Flow.Launcher/Properties/Resources.fr-FR.resx
deleted file mode 100644
index ca0f66f53..000000000
--- a/Flow.Launcher/Properties/Resources.fr-FR.resx
+++ /dev/null
@@ -1,130 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 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
From 78ffeb8cf2508c56eb40bb027ca3ce73c551fe24 Mon Sep 17 00:00:00 2001
From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Fri, 13 Jun 2025 00:24:40 +0800
Subject: [PATCH 1534/1697] Delete
Flow.Launcher/Properties/Resources.he-IL.resx
---
Flow.Launcher/Properties/Resources.he-IL.resx | 130 ------------------
1 file changed, 130 deletions(-)
delete mode 100644 Flow.Launcher/Properties/Resources.he-IL.resx
diff --git a/Flow.Launcher/Properties/Resources.he-IL.resx b/Flow.Launcher/Properties/Resources.he-IL.resx
deleted file mode 100644
index ca0f66f53..000000000
--- a/Flow.Launcher/Properties/Resources.he-IL.resx
+++ /dev/null
@@ -1,130 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 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
From 3eb5fead1f790120729f740a97cf9959a39a417a Mon Sep 17 00:00:00 2001
From: Jeremy
Date: Wed, 11 Jun 2025 21:10:56 +1000
Subject: [PATCH 1535/1697] remove on tag deployment & change NuGet publish to
on master push
---
appveyor.yml | 11 +----------
1 file changed, 1 insertion(+), 10 deletions(-)
diff --git a/appveyor.yml b/appveyor.yml
index fa0b5956b..8fba05252 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -62,7 +62,7 @@ deploy:
api_key:
secure: sCSd5JWgdzJWDa9kpqECut5ACPKZqcoxKU8ERKC00k7VIjig3/+nFV5zzTcGb0w3
on:
- APPVEYOR_REPO_TAG: true
+ branch: master
- provider: GitHub
repository: Flow-Launcher/Prereleases
@@ -84,12 +84,3 @@ deploy:
force_update: true
on:
branch: master
-
- - provider: GitHub
- release: v$(flowVersion)
- auth_token:
- secure: ij4UeXUYQBDJxn2YRAAhUOjklOGVKDB87Hn5J8tKIzj13yatoI7sLM666QDQFEgv
- artifact: Squirrel Installer, Portable Version, Squirrel nupkg, Squirrel RELEASES
- force_update: true
- on:
- APPVEYOR_REPO_TAG: true
From 8f43de696731c7bb535d77a96e9f843de16e20b4 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 6 Jun 2025 13:12:40 +0800
Subject: [PATCH 1536/1697] Support Msix FireFox bookmarks
---
.../FirefoxBookmarkLoader.cs | 165 +++++++++++-------
1 file changed, 98 insertions(+), 67 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
index acace2506..42a288e3a 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
@@ -264,84 +264,115 @@ public class FirefoxBookmarkLoader : FirefoxBookmarkLoaderBase
///
public override List GetBookmarks()
{
- return GetBookmarksFromPath(PlacesPath);
+ var bookmarks1 = GetBookmarksFromPath(PlacesPath);
+ var bookmarks2 = GetBookmarksFromPath(MsixPlacesPath);
+ return bookmarks1.Concat(bookmarks2).ToList();
}
///
- /// Path to places.sqlite
+ /// Path to places.sqlite of Msi installer
+ /// E.g. C:\Users\{UserName}\AppData\Roaming\Mozilla\Firefox
+ ///
///
- ///
private static string PlacesPath
{
get
{
var profileFolderPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"Mozilla\Firefox");
- var profileIni = Path.Combine(profileFolderPath, @"profiles.ini");
-
- if (!File.Exists(profileIni))
- return string.Empty;
-
- // get firefox default profile directory from profiles.ini
- using var sReader = new StreamReader(profileIni);
- var ini = sReader.ReadToEnd();
-
- var lines = ini.Split("\r\n").ToList();
-
- var defaultProfileFolderNameRaw = lines.FirstOrDefault(x => x.Contains("Default=") && x != "Default=1") ?? string.Empty;
-
- if (string.IsNullOrEmpty(defaultProfileFolderNameRaw))
- return string.Empty;
-
- var defaultProfileFolderName = defaultProfileFolderNameRaw.Split('=').Last();
-
- var indexOfDefaultProfileAttributePath = lines.IndexOf("Path=" + defaultProfileFolderName);
-
- /*
- Current profiles.ini structure example as of Firefox version 69.0.1
-
- [Install736426B0AF4A39CB]
- Default=Profiles/7789f565.default-release <== this is the default profile this plugin will get the bookmarks from. When opened Firefox will load the default profile
- Locked=1
-
- [Profile2]
- Name=newblahprofile
- IsRelative=0
- Path=C:\t6h2yuq8.newblahprofile <== Note this is a custom location path for the profile user can set, we need to cater for this in code.
-
- [Profile1]
- Name=default
- IsRelative=1
- Path=Profiles/cydum7q4.default
- Default=1
-
- [Profile0]
- Name=default-release
- IsRelative=1
- Path=Profiles/7789f565.default-release
-
- [General]
- StartWithLastProfile=1
- Version=2
- */
- // Seen in the example above, the IsRelative attribute is always above the Path attribute
-
- var relativePath = Path.Combine(defaultProfileFolderName, "places.sqlite");
- var absoluePath = Path.Combine(profileFolderPath, relativePath);
-
- // If the index is out of range, it means that the default profile is in a custom location or the file is malformed
- // If the profile is in a custom location, we need to check
- if (indexOfDefaultProfileAttributePath - 1 < 0 ||
- indexOfDefaultProfileAttributePath - 1 >= lines.Count)
- {
- return Directory.Exists(absoluePath) ? absoluePath : relativePath;
- }
-
- var relativeAttribute = lines[indexOfDefaultProfileAttributePath - 1];
-
- return relativeAttribute == "0" // See above, the profile is located in a custom location, path is not relative, so IsRelative=0
- ? relativePath : absoluePath;
+ return GetProfileIniPath(profileFolderPath);
}
}
+
+ ///
+ /// Path to places.sqlite of MSIX installer
+ /// E.g. C:\Users\{UserName}\AppData\Local\Packages\Mozilla.Firefox_n80bbvh6b1yt2\LocalCache\Roaming\Mozilla\Firefox
+ ///
+ ///
+ public static string MsixPlacesPath
+ {
+ get
+ {
+ var platformPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
+ var packagesPath = Path.Combine(platformPath, "Packages");
+
+ // Search for folder with Mozilla.Firefox prefix
+ var firefoxPackageFolder = Directory.EnumerateDirectories(packagesPath, "Mozilla.Firefox*",
+ SearchOption.TopDirectoryOnly).FirstOrDefault();
+
+ // Msix FireFox not installed
+ if (firefoxPackageFolder == null) return string.Empty;
+
+ var profileFolderPath = Path.Combine(firefoxPackageFolder, @"LocalCache\Roaming\Mozilla\Firefox");
+ return GetProfileIniPath(profileFolderPath);
+ }
+ }
+
+ private static string GetProfileIniPath(string profileFolderPath)
+ {
+ var profileIni = Path.Combine(profileFolderPath, @"profiles.ini");
+ if (!File.Exists(profileIni))
+ return string.Empty;
+
+ // get firefox default profile directory from profiles.ini
+ using var sReader = new StreamReader(profileIni);
+ var ini = sReader.ReadToEnd();
+
+ var lines = ini.Split("\r\n").ToList();
+
+ var defaultProfileFolderNameRaw = lines.FirstOrDefault(x => x.Contains("Default=") && x != "Default=1") ?? string.Empty;
+
+ if (string.IsNullOrEmpty(defaultProfileFolderNameRaw))
+ return string.Empty;
+
+ var defaultProfileFolderName = defaultProfileFolderNameRaw.Split('=').Last();
+
+ var indexOfDefaultProfileAttributePath = lines.IndexOf("Path=" + defaultProfileFolderName);
+
+ /*
+ Current profiles.ini structure example as of Firefox version 69.0.1
+
+ [Install736426B0AF4A39CB]
+ Default=Profiles/7789f565.default-release <== this is the default profile this plugin will get the bookmarks from. When opened Firefox will load the default profile
+ Locked=1
+
+ [Profile2]
+ Name=newblahprofile
+ IsRelative=0
+ Path=C:\t6h2yuq8.newblahprofile <== Note this is a custom location path for the profile user can set, we need to cater for this in code.
+
+ [Profile1]
+ Name=default
+ IsRelative=1
+ Path=Profiles/cydum7q4.default
+ Default=1
+
+ [Profile0]
+ Name=default-release
+ IsRelative=1
+ Path=Profiles/7789f565.default-release
+
+ [General]
+ StartWithLastProfile=1
+ Version=2
+ */
+ // Seen in the example above, the IsRelative attribute is always above the Path attribute
+
+ var relativePath = Path.Combine(defaultProfileFolderName, "places.sqlite");
+ var absoluePath = Path.Combine(profileFolderPath, relativePath);
+
+ // If the index is out of range, it means that the default profile is in a custom location or the file is malformed
+ // If the profile is in a custom location, we need to check
+ if (indexOfDefaultProfileAttributePath - 1 < 0 ||
+ indexOfDefaultProfileAttributePath - 1 >= lines.Count)
+ {
+ return Directory.Exists(absoluePath) ? absoluePath : relativePath;
+ }
+
+ var relativeAttribute = lines[indexOfDefaultProfileAttributePath - 1];
+
+ return relativeAttribute == "0" // See above, the profile is located in a custom location, path is not relative, so IsRelative=0
+ ? relativePath : absoluePath;
+ }
}
public static class Extensions
From 281e042ab7016621c649defcca942cf854cd6129 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 6 Jun 2025 13:21:51 +0800
Subject: [PATCH 1537/1697] Fix IsRelative logic.
---
.../FirefoxBookmarkLoader.cs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
index 42a288e3a..61fd05073 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
@@ -370,7 +370,8 @@ public class FirefoxBookmarkLoader : FirefoxBookmarkLoaderBase
var relativeAttribute = lines[indexOfDefaultProfileAttributePath - 1];
- return relativeAttribute == "0" // See above, the profile is located in a custom location, path is not relative, so IsRelative=0
+ // See above, the profile is located in a custom location, path is not relative, so IsRelative=0
+ return (relativeAttribute == "0" || relativeAttribute == "IsRelative=0")
? relativePath : absoluePath;
}
}
From ceb05e8651f847cddf9e2fa00d15a1ef741f56b4 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 6 Jun 2025 13:25:43 +0800
Subject: [PATCH 1538/1697] Add error handling for directory operation
---
.../FirefoxBookmarkLoader.cs | 22 ++++++++++++-------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
index 61fd05073..ac382275f 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
@@ -294,16 +294,22 @@ public class FirefoxBookmarkLoader : FirefoxBookmarkLoaderBase
{
var platformPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
var packagesPath = Path.Combine(platformPath, "Packages");
-
- // Search for folder with Mozilla.Firefox prefix
- var firefoxPackageFolder = Directory.EnumerateDirectories(packagesPath, "Mozilla.Firefox*",
- SearchOption.TopDirectoryOnly).FirstOrDefault();
+ try
+ {
+ // Search for folder with Mozilla.Firefox prefix
+ var firefoxPackageFolder = Directory.EnumerateDirectories(packagesPath, "Mozilla.Firefox*",
+ SearchOption.TopDirectoryOnly).FirstOrDefault();
- // Msix FireFox not installed
- if (firefoxPackageFolder == null) return string.Empty;
+ // Msix FireFox not installed
+ if (firefoxPackageFolder == null) return string.Empty;
- var profileFolderPath = Path.Combine(firefoxPackageFolder, @"LocalCache\Roaming\Mozilla\Firefox");
- return GetProfileIniPath(profileFolderPath);
+ var profileFolderPath = Path.Combine(firefoxPackageFolder, @"LocalCache\Roaming\Mozilla\Firefox");
+ return GetProfileIniPath(profileFolderPath);
+ }
+ catch
+ {
+ return string.Empty;
+ }
}
}
From aaa8e4dc780900ce721555dba06c22fb6dd3de13 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 8 Jun 2025 12:09:07 +0800
Subject: [PATCH 1539/1697] Use AddRange
---
.../FirefoxBookmarkLoader.cs | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
index ac382275f..dcf7763c3 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
@@ -264,9 +264,10 @@ public class FirefoxBookmarkLoader : FirefoxBookmarkLoaderBase
///
public override List GetBookmarks()
{
- var bookmarks1 = GetBookmarksFromPath(PlacesPath);
- var bookmarks2 = GetBookmarksFromPath(MsixPlacesPath);
- return bookmarks1.Concat(bookmarks2).ToList();
+ var bookmarks = new List();
+ bookmarks.AddRange(GetBookmarksFromPath(PlacesPath));
+ bookmarks.AddRange(GetBookmarksFromPath(MsixPlacesPath));
+ return bookmarks;
}
///
From 44304f25d68de8dd53b9a1ac414cffbffa07f2fb Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 11 Jun 2025 21:14:05 +0800
Subject: [PATCH 1540/1697] Change code comments
---
.../FirefoxBookmarkLoader.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
index dcf7763c3..f214997c3 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
@@ -343,9 +343,9 @@ public class FirefoxBookmarkLoader : FirefoxBookmarkLoaderBase
Locked=1
[Profile2]
- Name=newblahprofile
+ Name=dummyprofile
IsRelative=0
- Path=C:\t6h2yuq8.newblahprofile <== Note this is a custom location path for the profile user can set, we need to cater for this in code.
+ Path=C:\t6h2yuq8.dummyprofile <== Note this is a custom location path for the profile user can set, we need to cater for this in code.
[Profile1]
Name=default
From 16fd256fd61873320691acd774c87cf7df4ee8be Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 12 Jun 2025 16:27:48 +0800
Subject: [PATCH 1541/1697] Fix typos
---
.../FirefoxBookmarkLoader.cs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
index f214997c3..8dffeecdc 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
@@ -365,21 +365,21 @@ public class FirefoxBookmarkLoader : FirefoxBookmarkLoaderBase
// Seen in the example above, the IsRelative attribute is always above the Path attribute
var relativePath = Path.Combine(defaultProfileFolderName, "places.sqlite");
- var absoluePath = Path.Combine(profileFolderPath, relativePath);
+ var absolutePath = Path.Combine(profileFolderPath, relativePath);
// If the index is out of range, it means that the default profile is in a custom location or the file is malformed
// If the profile is in a custom location, we need to check
if (indexOfDefaultProfileAttributePath - 1 < 0 ||
indexOfDefaultProfileAttributePath - 1 >= lines.Count)
{
- return Directory.Exists(absoluePath) ? absoluePath : relativePath;
+ return Directory.Exists(absolutePath) ? absolutePath : relativePath;
}
var relativeAttribute = lines[indexOfDefaultProfileAttributePath - 1];
// See above, the profile is located in a custom location, path is not relative, so IsRelative=0
return (relativeAttribute == "0" || relativeAttribute == "IsRelative=0")
- ? relativePath : absoluePath;
+ ? relativePath : absolutePath;
}
}
From fba42fff1799f8a2c9e9e68e7ab067a17a4690a2 Mon Sep 17 00:00:00 2001
From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Fri, 13 Jun 2025 22:31:28 +0800
Subject: [PATCH 1542/1697] Fix transaltion logic
---
.../PinyinAlphabet.cs | 46 +++++++++----------
1 file changed, 22 insertions(+), 24 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
index 1637a285c..090abb490 100644
--- a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
+++ b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
@@ -32,14 +32,14 @@ namespace Flow.Launcher.Infrastructure
{
if (_settings.ShouldUsePinyin)
{
- if (!_pinyinCache.TryGetValue(content, out var value))
+ if (true)
{
return BuildCacheFromContent(content);
}
- else
- {
- return value;
- }
+ //else
+ //{
+ // return value;
+ //}
}
return (content, null);
}
@@ -164,11 +164,10 @@ namespace Flow.Launcher.Infrastructure
// Check for initials that are two characters long (zh, ch, sh)
if (fullPinyin.Length >= 2)
{
- var firstTwo = fullPinyinSpan[..2];
- var firstTwoString = firstTwo.ToString();
- if (first.ContainsKey(firstTwoString))
+ var firstTwoString = fullPinyinSpan[..2].ToString();
+ if (first.TryGetValue(firstTwoString, out var firstTwoDoublePin))
{
- doublePin.Append(firstTwoString);
+ doublePin.Append(firstTwoDoublePin);
var lastTwo = fullPinyinSpan[2..];
var lastTwoString = lastTwo.ToString();
@@ -178,27 +177,26 @@ namespace Flow.Launcher.Infrastructure
}
else
{
- doublePin.Append(lastTwo);
+ doublePin.Append(lastTwo); // Todo: original pinyin, remove this line if not needed
}
}
- }
- // Handle single-character initials
- else
- {
- doublePin.Append(fullPinyinSpan[0]);
-
- var lastOne = fullPinyinSpan[1..];
- var lastOneString = lastOne.ToString();
- if (second.TryGetValue(lastOneString, out var tmp))
- {
- doublePin.Append(tmp);
- }
else
{
- doublePin.Append(lastOne);
+ // Handle single-character initials
+ doublePin.Append(fullPinyinSpan[0]);
+
+ var lastOne = fullPinyinSpan[1..];
+ var lastOneString = lastOne.ToString();
+ if (second.TryGetValue(lastOneString, out var tmp))
+ {
+ doublePin.Append(tmp);
+ }
+ else
+ {
+ doublePin.Append(lastOne);
+ }
}
}
-
return doublePin.ToString();
}
From b31a7408d3c279e92480530fc6a8cd8167b435c2 Mon Sep 17 00:00:00 2001
From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Fri, 13 Jun 2025 23:39:14 +0800
Subject: [PATCH 1543/1697] Simple refactor
---
Flow.Launcher.Infrastructure/PinyinAlphabet.cs | 18 ++++++------------
1 file changed, 6 insertions(+), 12 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
index 090abb490..2c548e0a3 100644
--- a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
+++ b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
@@ -30,18 +30,12 @@ namespace Flow.Launcher.Infrastructure
public (string translation, TranslationMapping map) Translate(string content)
{
- if (_settings.ShouldUsePinyin)
- {
- if (true)
- {
- return BuildCacheFromContent(content);
- }
- //else
- //{
- // return value;
- //}
- }
- return (content, null);
+ if (!_settings.ShouldUsePinyin)
+ return (content, null);
+
+ return _pinyinCache.TryGetValue(content, out var value)
+ ? value
+ : BuildCacheFromContent(content);
}
private (string translation, TranslationMapping map) BuildCacheFromContent(string content)
From 818aac715e47aa0bcda35b2431dbeda4219bb88d Mon Sep 17 00:00:00 2001
From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Sat, 14 Jun 2025 14:32:00 +0800
Subject: [PATCH 1544/1697] Use lookup table to translate full pinyin to double
pinyin
---
.../PinyinAlphabet.cs | 166 +-
.../UserSettings/Settings.cs | 2 +
Flow.Launcher/Flow.Launcher.csproj | 3 +
Flow.Launcher/Resources/double_pinyin.json | 3746 +++++++++++++++++
4 files changed, 3805 insertions(+), 112 deletions(-)
create mode 100644 Flow.Launcher/Resources/double_pinyin.json
diff --git a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
index 2c548e0a3..6a2cd1e66 100644
--- a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
+++ b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
@@ -2,10 +2,13 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
+using System.IO;
using System.Text;
+using System.Text.Json;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Infrastructure.UserSettings;
using ToolGood.Words.Pinyin;
+using Flow.Launcher.Infrastructure.Logger;
namespace Flow.Launcher.Infrastructure
{
@@ -16,9 +19,49 @@ namespace Flow.Launcher.Infrastructure
private readonly Settings _settings;
+ private ReadOnlyDictionary currentDoublePinyinTable;
+
public PinyinAlphabet()
{
_settings = Ioc.Default.GetRequiredService();
+ LoadDoublePinyinTable();
+
+ _settings.PropertyChanged += (sender, e) =>
+ {
+ if (e.PropertyName == nameof(Settings.UseDoublePinyin) ||
+ e.PropertyName == nameof(Settings.DoublePinyinSchema))
+ {
+ LoadDoublePinyinTable();
+ _pinyinCache.Clear();
+ }
+ };
+ }
+
+ private void LoadDoublePinyinTable()
+ {
+ if (_settings.UseDoublePinyin)
+ {
+ var tablePath = Path.Join(AppContext.BaseDirectory, "Resources", "double_pinyin.json");
+ try
+ {
+ using var fs = File.OpenRead(tablePath);
+ Dictionary> table = JsonSerializer.Deserialize>>(fs);
+ if (!table.TryGetValue(_settings.DoublePinyinSchema, out var value))
+ {
+ throw new InvalidOperationException("DoublePinyinSchema is invalid.");
+ }
+ currentDoublePinyinTable = new ReadOnlyDictionary(value);
+ }
+ catch (System.Exception e)
+ {
+ Log.Exception(nameof(PinyinAlphabet), "Failed to load double pinyin table from file: " + tablePath, e);
+ currentDoublePinyinTable = new ReadOnlyDictionary(new Dictionary());
+ }
+ }
+ else
+ {
+ currentDoublePinyinTable = new ReadOnlyDictionary(new Dictionary());
+ }
}
public bool ShouldTranslate(string stringToTranslate)
@@ -50,7 +93,7 @@ namespace Flow.Launcher.Infrastructure
var resultBuilder = new StringBuilder();
var map = new TranslationMapping();
- var pre = false;
+ var previousIsChinese = false;
for (var i = 0; i < resultList.Length; i++)
{
@@ -58,18 +101,19 @@ namespace Flow.Launcher.Infrastructure
{
string dp = _settings.UseDoublePinyin ? ToDoublePin(resultList[i]) : resultList[i];
map.AddNewIndex(i, resultBuilder.Length, dp.Length + 1);
- resultBuilder.Append(' ');
+ if (previousIsChinese)
+ {
+ resultBuilder.Append(' ');
+ }
resultBuilder.Append(dp);
- pre = true;
}
else
{
- if (pre)
+ if (previousIsChinese)
{
- pre = false;
+ previousIsChinese = false;
resultBuilder.Append(' ');
}
-
resultBuilder.Append(resultList[i]);
}
}
@@ -83,115 +127,13 @@ namespace Flow.Launcher.Infrastructure
#region Double Pinyin
- private static readonly ReadOnlyDictionary special = new(new Dictionary(){
- {"A", "aa"},
- {"Ai", "ai"},
- {"An", "an"},
- {"Ang", "ah"},
- {"Ao", "ao"},
- {"E", "ee"},
- {"Ei", "ei"},
- {"En", "en"},
- {"Er", "er"},
- {"O", "oo"},
- {"Ou", "ou"}
- });
-
- private static readonly ReadOnlyDictionary first = new(new Dictionary(){
- {"Ch", "i"},
- {"Sh", "u"},
- {"Zh", "v"}
- });
-
- private static readonly ReadOnlyDictionary second = new(new Dictionary()
+ private string ToDoublePin(string fullPinyin)
{
- {"ua", "x"},
- {"ei", "w"},
- {"e", "e"},
- {"ou", "z"},
- {"iu", "q"},
- {"ve", "t"},
- {"ue", "t"},
- {"u", "u"},
- {"i", "i"},
- {"o", "o"},
- {"uo", "o"},
- {"ie", "p"},
- {"a", "a"},
- {"ong", "s"},
- {"iong", "s"},
- {"ai", "d"},
- {"ing", "k"},
- {"uai", "k"},
- {"ang", "h"},
- {"uan", "r"},
- {"an", "j"},
- {"en", "f"},
- {"ia", "x"},
- {"iang", "l"},
- {"uang", "l"},
- {"eng", "g"},
- {"in", "b"},
- {"ao", "c"},
- {"v", "v"},
- {"ui", "v"},
- {"un", "y"},
- {"iao", "n"},
- {"ian", "m"}
- });
-
- private static string ToDoublePin(string fullPinyin)
- {
- // Assuming s is valid
- var fullPinyinSpan = fullPinyin.AsSpan();
- var doublePin = new StringBuilder();
-
- // Handle special cases (a, o, e)
- if (fullPinyin.Length <= 3 && (fullPinyinSpan[0] == 'a' || fullPinyinSpan[0] == 'e' || fullPinyinSpan[0] == 'o'))
+ if (currentDoublePinyinTable.TryGetValue(fullPinyin, out var doublePinyinValue))
{
- if (special.TryGetValue(fullPinyin, out var value))
- {
- return value;
- }
+ return doublePinyinValue;
}
-
- // Check for initials that are two characters long (zh, ch, sh)
- if (fullPinyin.Length >= 2)
- {
- var firstTwoString = fullPinyinSpan[..2].ToString();
- if (first.TryGetValue(firstTwoString, out var firstTwoDoublePin))
- {
- doublePin.Append(firstTwoDoublePin);
-
- var lastTwo = fullPinyinSpan[2..];
- var lastTwoString = lastTwo.ToString();
- if (second.TryGetValue(lastTwoString, out var tmp))
- {
- doublePin.Append(tmp);
- }
- else
- {
- doublePin.Append(lastTwo); // Todo: original pinyin, remove this line if not needed
- }
- }
- else
- {
- // Handle single-character initials
- doublePin.Append(fullPinyinSpan[0]);
-
- var lastOne = fullPinyinSpan[1..];
- var lastOneString = lastOne.ToString();
- if (second.TryGetValue(lastOneString, out var tmp))
- {
- doublePin.Append(tmp);
- }
- else
- {
- doublePin.Append(lastOne);
- }
- }
- }
- return doublePin.ToString();
+ return fullPinyin;
}
#endregion
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index b10f9502e..e7306e3dd 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -292,6 +292,8 @@ namespace Flow.Launcher.Infrastructure.UserSettings
public bool UseDoublePinyin { get; set; } = true; //For developing
+ public string DoublePinyinSchema { get; set; } = "XiaoHe"; //For developing
+
public bool AlwaysPreview { get; set; } = false;
public bool AlwaysStartEn { get; set; } = false;
diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj
index d75d15a21..37e1f6bcf 100644
--- a/Flow.Launcher/Flow.Launcher.csproj
+++ b/Flow.Launcher/Flow.Launcher.csproj
@@ -127,6 +127,9 @@
PreserveNewest
+
+ PreserveNewest
+
diff --git a/Flow.Launcher/Resources/double_pinyin.json b/Flow.Launcher/Resources/double_pinyin.json
new file mode 100644
index 000000000..6b8ae06c0
--- /dev/null
+++ b/Flow.Launcher/Resources/double_pinyin.json
@@ -0,0 +1,3746 @@
+{
+ "XiaoHe": {
+ "Lv": "lv",
+ "Lve": "lt",
+ "Lue": "lt",
+ "Nv": "nv",
+ "Nve": "nt",
+ "Nue": "nt",
+ "A": "aa",
+ "O": "oo",
+ "E": "ee",
+ "Ai": "ai",
+ "Ei": "ei",
+ "Ao": "ao",
+ "Ou": "ou",
+ "An": "an",
+ "En": "en",
+ "Ang": "ah",
+ "Eng": "eg",
+ "Er": "er",
+ "Yi": "yi",
+ "Ya": "ya",
+ "Yo": "yo",
+ "Ye": "ye",
+ "Yao": "yc",
+ "You": "yz",
+ "Yan": "yj",
+ "Yin": "yb",
+ "Yang": "yh",
+ "Ying": "yk",
+ "Wu": "wu",
+ "Wa": "wa",
+ "Wo": "wo",
+ "Wai": "wd",
+ "Wei": "ww",
+ "Wan": "wj",
+ "Wen": "wf",
+ "Wang": "wh",
+ "Weng": "wg",
+ "Yu": "yu",
+ "Yue": "yt",
+ "Yuan": "yr",
+ "Yun": "yy",
+ "Yong": "ys",
+ "Ba": "ba",
+ "Bai": "bd",
+ "Ban": "bj",
+ "Bang": "bh",
+ "Bao": "bc",
+ "Bei": "bw",
+ "Ben": "bf",
+ "Beng": "bg",
+ "Bi": "bi",
+ "Bian": "bm",
+ "Biang": "bl",
+ "Biao": "bn",
+ "Bie": "bp",
+ "Bin": "bb",
+ "Bing": "bk",
+ "Bo": "bo",
+ "Bu": "bu",
+ "Ca": "ca",
+ "Cai": "cd",
+ "Can": "cj",
+ "Cang": "ch",
+ "Cao": "cc",
+ "Ce": "ce",
+ "Cen": "cf",
+ "Ceng": "cg",
+ "Cha": "ia",
+ "Chai": "id",
+ "Chan": "ij",
+ "Chang": "ih",
+ "Chao": "ic",
+ "Che": "ie",
+ "Chen": "if",
+ "Cheng": "ig",
+ "Chi": "ii",
+ "Chong": "is",
+ "Chou": "iz",
+ "Chu": "iu",
+ "Chua": "ix",
+ "Chuai": "ik",
+ "Chuan": "ir",
+ "Chuang": "il",
+ "Chui": "iv",
+ "Chun": "iy",
+ "Chuo": "io",
+ "Ci": "ci",
+ "Cong": "cs",
+ "Cou": "cz",
+ "Cu": "cu",
+ "Cuan": "cr",
+ "Cui": "cv",
+ "Cun": "cy",
+ "Cuo": "co",
+ "Da": "da",
+ "Dai": "dd",
+ "Dan": "dj",
+ "Dang": "dh",
+ "Dao": "dc",
+ "De": "de",
+ "Dei": "dw",
+ "Den": "df",
+ "Deng": "dg",
+ "Di": "di",
+ "Dia": "dx",
+ "Dian": "dm",
+ "Diao": "dn",
+ "Die": "dp",
+ "Ding": "dk",
+ "Diu": "dq",
+ "Dong": "ds",
+ "Dou": "dz",
+ "Du": "du",
+ "Duan": "dr",
+ "Dui": "dv",
+ "Dun": "dy",
+ "Duo": "do",
+ "Fa": "fa",
+ "Fan": "fj",
+ "Fang": "fh",
+ "Fei": "fw",
+ "Fen": "ff",
+ "Feng": "fg",
+ "Fiao": "fn",
+ "Fo": "fo",
+ "Fou": "fz",
+ "Fu": "fu",
+ "Ga": "ga",
+ "Gai": "gd",
+ "Gan": "gj",
+ "Gang": "gh",
+ "Gao": "gc",
+ "Ge": "ge",
+ "Gei": "gw",
+ "Gen": "gf",
+ "Geng": "gg",
+ "Gong": "gs",
+ "Gou": "gz",
+ "Gu": "gu",
+ "Gua": "gx",
+ "Guai": "gk",
+ "Guan": "gr",
+ "Guang": "gl",
+ "Gui": "gv",
+ "Gun": "gy",
+ "Guo": "go",
+ "Ha": "ha",
+ "Hai": "hd",
+ "Han": "hj",
+ "Hang": "hh",
+ "Hao": "hc",
+ "He": "he",
+ "Hei": "hw",
+ "Hen": "hf",
+ "Heng": "hg",
+ "Hong": "hs",
+ "Hou": "hz",
+ "Hu": "hu",
+ "Hua": "hx",
+ "Huai": "hk",
+ "Huan": "hr",
+ "Huang": "hl",
+ "Hui": "hv",
+ "Hun": "hy",
+ "Huo": "ho",
+ "Ji": "ji",
+ "Jia": "jx",
+ "Jian": "jm",
+ "Jiang": "jl",
+ "Jiao": "jn",
+ "Jie": "jp",
+ "Jin": "jb",
+ "Jing": "jk",
+ "Jiong": "js",
+ "Jiu": "jq",
+ "Ju": "ju",
+ "Juan": "jr",
+ "Jue": "jt",
+ "Jun": "jy",
+ "Ka": "ka",
+ "Kai": "kd",
+ "Kan": "kj",
+ "Kang": "kh",
+ "Kao": "kc",
+ "Ke": "ke",
+ "Ken": "kf",
+ "Keng": "kg",
+ "Kong": "ks",
+ "Kou": "kz",
+ "Ku": "ku",
+ "Kua": "kx",
+ "Kuai": "kk",
+ "Kuan": "kr",
+ "Kuang": "kl",
+ "Kui": "kv",
+ "Kun": "ky",
+ "Kuo": "ko",
+ "La": "la",
+ "Lai": "ld",
+ "Lan": "lj",
+ "Lang": "lh",
+ "Lao": "lc",
+ "Le": "le",
+ "Lei": "lw",
+ "Leng": "lg",
+ "Li": "li",
+ "Lia": "lx",
+ "Lian": "lm",
+ "Liang": "ll",
+ "Liao": "ln",
+ "Lie": "lp",
+ "Lin": "lb",
+ "Ling": "lk",
+ "Liu": "lq",
+ "Lo": "lo",
+ "Long": "ls",
+ "Lou": "lz",
+ "Lu": "lu",
+ "Luan": "lr",
+ "Lun": "ly",
+ "Luo": "lo",
+ "Ma": "ma",
+ "Mai": "md",
+ "Man": "mj",
+ "Mang": "mh",
+ "Mao": "mc",
+ "Me": "me",
+ "Mei": "mw",
+ "Men": "mf",
+ "Meng": "mg",
+ "Mi": "mi",
+ "Mian": "mm",
+ "Miao": "mn",
+ "Mie": "mp",
+ "Min": "mb",
+ "Ming": "mk",
+ "Miu": "mq",
+ "Mo": "mo",
+ "Mou": "mz",
+ "Mu": "mu",
+ "Na": "na",
+ "Nai": "nd",
+ "Nan": "nj",
+ "Nang": "nh",
+ "Nao": "nc",
+ "Ne": "ne",
+ "Nei": "nw",
+ "Nen": "nf",
+ "Neng": "ng",
+ "Ni": "ni",
+ "Nian": "nm",
+ "Niang": "nl",
+ "Niao": "nn",
+ "Nie": "np",
+ "Nin": "nb",
+ "Ning": "nk",
+ "Niu": "nq",
+ "Nong": "ns",
+ "Nou": "nz",
+ "Nu": "nu",
+ "Nuan": "nr",
+ "Nun": "ny",
+ "Nuo": "no",
+ "Pa": "pa",
+ "Pai": "pd",
+ "Pan": "pj",
+ "Pang": "ph",
+ "Pao": "pc",
+ "Pei": "pw",
+ "Pen": "pf",
+ "Peng": "pg",
+ "Pi": "pi",
+ "Pian": "pm",
+ "Piao": "pn",
+ "Pie": "pp",
+ "Pin": "pb",
+ "Ping": "pk",
+ "Po": "po",
+ "Pou": "pz",
+ "Pu": "pu",
+ "Qi": "qi",
+ "Qia": "qx",
+ "Qian": "qm",
+ "Qiang": "ql",
+ "Qiao": "qn",
+ "Qie": "qp",
+ "Qin": "qb",
+ "Qing": "qk",
+ "Qiong": "qs",
+ "Qiu": "qq",
+ "Qu": "qu",
+ "Quan": "qr",
+ "Que": "qt",
+ "Qun": "qy",
+ "Ran": "rj",
+ "Rang": "rh",
+ "Rao": "rc",
+ "Re": "re",
+ "Ren": "rf",
+ "Reng": "rg",
+ "Ri": "ri",
+ "Rong": "rs",
+ "Rou": "rz",
+ "Ru": "ru",
+ "Rua": "rx",
+ "Ruan": "rr",
+ "Rui": "rv",
+ "Run": "ry",
+ "Ruo": "ro",
+ "Sa": "sa",
+ "Sai": "sd",
+ "San": "sj",
+ "Sang": "sh",
+ "Sao": "sc",
+ "Se": "se",
+ "Sen": "sf",
+ "Seng": "sg",
+ "Sha": "ua",
+ "Shai": "ud",
+ "Shan": "uj",
+ "Shang": "uh",
+ "Shao": "uc",
+ "She": "ue",
+ "Shei": "uw",
+ "Shen": "uf",
+ "Sheng": "ug",
+ "Shi": "ui",
+ "Shou": "uz",
+ "Shu": "uu",
+ "Shua": "ux",
+ "Shuai": "uk",
+ "Shuan": "ur",
+ "Shuang": "ul",
+ "Shui": "uv",
+ "Shun": "uy",
+ "Shuo": "uo",
+ "Si": "si",
+ "Song": "ss",
+ "Sou": "sz",
+ "Su": "su",
+ "Suan": "sr",
+ "Sui": "sv",
+ "Sun": "sy",
+ "Suo": "so",
+ "Ta": "ta",
+ "Tai": "td",
+ "Tan": "tj",
+ "Tang": "th",
+ "Tao": "tc",
+ "Te": "te",
+ "Tei": "tw",
+ "Teng": "tg",
+ "Ti": "ti",
+ "Tian": "tm",
+ "Tiao": "tn",
+ "Tie": "tp",
+ "Ting": "tk",
+ "Tong": "ts",
+ "Tou": "tz",
+ "Tu": "tu",
+ "Tuan": "tr",
+ "Tui": "tv",
+ "Tun": "ty",
+ "Tuo": "to",
+ "Xi": "xi",
+ "Xia": "xx",
+ "Xian": "xm",
+ "Xiang": "xl",
+ "Xiao": "xn",
+ "Xie": "xp",
+ "Xin": "xb",
+ "Xing": "xk",
+ "Xiong": "xs",
+ "Xiu": "xq",
+ "Xu": "xu",
+ "Xuan": "xr",
+ "Xue": "xt",
+ "Xun": "xy",
+ "Za": "za",
+ "Zai": "zd",
+ "Zan": "zj",
+ "Zang": "zh",
+ "Zao": "zc",
+ "Ze": "ze",
+ "Zei": "zw",
+ "Zen": "zf",
+ "Zeng": "zg",
+ "Zha": "va",
+ "Zhai": "vd",
+ "Zhan": "vj",
+ "Zhang": "vh",
+ "Zhao": "vc",
+ "Zhe": "ve",
+ "Zhen": "vf",
+ "Zheng": "vg",
+ "Zhi": "vi",
+ "Zhong": "vs",
+ "Zhou": "vz",
+ "Zhu": "vu",
+ "Zhua": "vx",
+ "Zhuai": "vk",
+ "Zhuan": "vr",
+ "Zhuang": "vl",
+ "Zhui": "vv",
+ "Zhun": "vy",
+ "Zhuo": "vo",
+ "Zi": "zi",
+ "Zong": "zs",
+ "Zou": "zz",
+ "Zu": "zu",
+ "Zuan": "zr",
+ "Zui": "zv",
+ "Zun": "zy",
+ "Zuo": "zo"
+ },
+ "ZiRanMa": {
+ "Lv": "lv",
+ "Lve": "lt",
+ "Lue": "lt",
+ "Nv": "nv",
+ "Nve": "nt",
+ "Nue": "nt",
+ "A": "aa",
+ "O": "oo",
+ "E": "ee",
+ "Ai": "ai",
+ "Ei": "ei",
+ "Ao": "ao",
+ "Ou": "ou",
+ "An": "an",
+ "En": "en",
+ "Ang": "ah",
+ "Eng": "eg",
+ "Er": "er",
+ "Yi": "yi",
+ "Ya": "ya",
+ "Yo": "yo",
+ "Ye": "ye",
+ "Yao": "yk",
+ "You": "yb",
+ "Yan": "yj",
+ "Yin": "yn",
+ "Yang": "yh",
+ "Ying": "yy",
+ "Wu": "wu",
+ "Wa": "wa",
+ "Wo": "wo",
+ "Wai": "wl",
+ "Wei": "wz",
+ "Wan": "wj",
+ "Wen": "wf",
+ "Wang": "wh",
+ "Weng": "wg",
+ "Yu": "yu",
+ "Yue": "yt",
+ "Yuan": "yr",
+ "Yun": "yp",
+ "Yong": "ys",
+ "Ba": "ba",
+ "Bai": "bl",
+ "Ban": "bj",
+ "Bang": "bh",
+ "Bao": "bk",
+ "Bei": "bz",
+ "Ben": "bf",
+ "Beng": "bg",
+ "Bi": "bi",
+ "Bian": "bm",
+ "Biang": "bd",
+ "Biao": "bc",
+ "Bie": "bx",
+ "Bin": "bn",
+ "Bing": "by",
+ "Bo": "bo",
+ "Bu": "bu",
+ "Ca": "ca",
+ "Cai": "cl",
+ "Can": "cj",
+ "Cang": "ch",
+ "Cao": "ck",
+ "Ce": "ce",
+ "Cen": "cf",
+ "Ceng": "cg",
+ "Cha": "ia",
+ "Chai": "il",
+ "Chan": "ij",
+ "Chang": "ih",
+ "Chao": "ik",
+ "Che": "ie",
+ "Chen": "if",
+ "Cheng": "ig",
+ "Chi": "ii",
+ "Chong": "is",
+ "Chou": "ib",
+ "Chu": "iu",
+ "Chua": "iw",
+ "Chuai": "iy",
+ "Chuan": "ir",
+ "Chuang": "id",
+ "Chui": "iv",
+ "Chun": "ip",
+ "Chuo": "io",
+ "Ci": "ci",
+ "Cong": "cs",
+ "Cou": "cb",
+ "Cu": "cu",
+ "Cuan": "cr",
+ "Cui": "cv",
+ "Cun": "cp",
+ "Cuo": "co",
+ "Da": "da",
+ "Dai": "dl",
+ "Dan": "dj",
+ "Dang": "dh",
+ "Dao": "dk",
+ "De": "de",
+ "Dei": "dz",
+ "Den": "df",
+ "Deng": "dg",
+ "Di": "di",
+ "Dia": "dw",
+ "Dian": "dm",
+ "Diao": "dc",
+ "Die": "dx",
+ "Ding": "dy",
+ "Diu": "dq",
+ "Dong": "ds",
+ "Dou": "db",
+ "Du": "du",
+ "Duan": "dr",
+ "Dui": "dv",
+ "Dun": "dp",
+ "Duo": "do",
+ "Fa": "fa",
+ "Fan": "fj",
+ "Fang": "fh",
+ "Fei": "fz",
+ "Fen": "ff",
+ "Feng": "fg",
+ "Fiao": "fc",
+ "Fo": "fo",
+ "Fou": "fb",
+ "Fu": "fu",
+ "Ga": "ga",
+ "Gai": "gl",
+ "Gan": "gj",
+ "Gang": "gh",
+ "Gao": "gk",
+ "Ge": "ge",
+ "Gei": "gz",
+ "Gen": "gf",
+ "Geng": "gg",
+ "Gong": "gs",
+ "Gou": "gb",
+ "Gu": "gu",
+ "Gua": "gw",
+ "Guai": "gy",
+ "Guan": "gr",
+ "Guang": "gd",
+ "Gui": "gv",
+ "Gun": "gp",
+ "Guo": "go",
+ "Ha": "ha",
+ "Hai": "hl",
+ "Han": "hj",
+ "Hang": "hh",
+ "Hao": "hk",
+ "He": "he",
+ "Hei": "hz",
+ "Hen": "hf",
+ "Heng": "hg",
+ "Hong": "hs",
+ "Hou": "hb",
+ "Hu": "hu",
+ "Hua": "hw",
+ "Huai": "hy",
+ "Huan": "hr",
+ "Huang": "hd",
+ "Hui": "hv",
+ "Hun": "hp",
+ "Huo": "ho",
+ "Ji": "ji",
+ "Jia": "jw",
+ "Jian": "jm",
+ "Jiang": "jd",
+ "Jiao": "jc",
+ "Jie": "jx",
+ "Jin": "jn",
+ "Jing": "jy",
+ "Jiong": "js",
+ "Jiu": "jq",
+ "Ju": "ju",
+ "Juan": "jr",
+ "Jue": "jt",
+ "Jun": "jp",
+ "Ka": "ka",
+ "Kai": "kl",
+ "Kan": "kj",
+ "Kang": "kh",
+ "Kao": "kk",
+ "Ke": "ke",
+ "Ken": "kf",
+ "Keng": "kg",
+ "Kong": "ks",
+ "Kou": "kb",
+ "Ku": "ku",
+ "Kua": "kw",
+ "Kuai": "ky",
+ "Kuan": "kr",
+ "Kuang": "kd",
+ "Kui": "kv",
+ "Kun": "kp",
+ "Kuo": "ko",
+ "La": "la",
+ "Lai": "ll",
+ "Lan": "lj",
+ "Lang": "lh",
+ "Lao": "lk",
+ "Le": "le",
+ "Lei": "lz",
+ "Leng": "lg",
+ "Li": "li",
+ "Lia": "lw",
+ "Lian": "lm",
+ "Liang": "ld",
+ "Liao": "lc",
+ "Lie": "lx",
+ "Lin": "ln",
+ "Ling": "ly",
+ "Liu": "lq",
+ "Lo": "lo",
+ "Long": "ls",
+ "Lou": "lb",
+ "Lu": "lu",
+ "Luan": "lr",
+ "Lun": "lp",
+ "Luo": "lo",
+ "Ma": "ma",
+ "Mai": "ml",
+ "Man": "mj",
+ "Mang": "mh",
+ "Mao": "mk",
+ "Me": "me",
+ "Mei": "mz",
+ "Men": "mf",
+ "Meng": "mg",
+ "Mi": "mi",
+ "Mian": "mm",
+ "Miao": "mc",
+ "Mie": "mx",
+ "Min": "mn",
+ "Ming": "my",
+ "Miu": "mq",
+ "Mo": "mo",
+ "Mou": "mb",
+ "Mu": "mu",
+ "Na": "na",
+ "Nai": "nl",
+ "Nan": "nj",
+ "Nang": "nh",
+ "Nao": "nk",
+ "Ne": "ne",
+ "Nei": "nz",
+ "Nen": "nf",
+ "Neng": "ng",
+ "Ni": "ni",
+ "Nian": "nm",
+ "Niang": "nd",
+ "Niao": "nc",
+ "Nie": "nx",
+ "Nin": "nn",
+ "Ning": "ny",
+ "Niu": "nq",
+ "Nong": "ns",
+ "Nou": "nb",
+ "Nu": "nu",
+ "Nuan": "nr",
+ "Nun": "np",
+ "Nuo": "no",
+ "Pa": "pa",
+ "Pai": "pl",
+ "Pan": "pj",
+ "Pang": "ph",
+ "Pao": "pk",
+ "Pei": "pz",
+ "Pen": "pf",
+ "Peng": "pg",
+ "Pi": "pi",
+ "Pian": "pm",
+ "Piao": "pc",
+ "Pie": "px",
+ "Pin": "pn",
+ "Ping": "py",
+ "Po": "po",
+ "Pou": "pb",
+ "Pu": "pu",
+ "Qi": "qi",
+ "Qia": "qw",
+ "Qian": "qm",
+ "Qiang": "qd",
+ "Qiao": "qc",
+ "Qie": "qx",
+ "Qin": "qn",
+ "Qing": "qy",
+ "Qiong": "qs",
+ "Qiu": "qq",
+ "Qu": "qu",
+ "Quan": "qr",
+ "Que": "qt",
+ "Qun": "qp",
+ "Ran": "rj",
+ "Rang": "rh",
+ "Rao": "rk",
+ "Re": "re",
+ "Ren": "rf",
+ "Reng": "rg",
+ "Ri": "ri",
+ "Rong": "rs",
+ "Rou": "rb",
+ "Ru": "ru",
+ "Rua": "rw",
+ "Ruan": "rr",
+ "Rui": "rv",
+ "Run": "rp",
+ "Ruo": "ro",
+ "Sa": "sa",
+ "Sai": "sl",
+ "San": "sj",
+ "Sang": "sh",
+ "Sao": "sk",
+ "Se": "se",
+ "Sen": "sf",
+ "Seng": "sg",
+ "Sha": "ua",
+ "Shai": "ul",
+ "Shan": "uj",
+ "Shang": "uh",
+ "Shao": "uk",
+ "She": "ue",
+ "Shei": "uz",
+ "Shen": "uf",
+ "Sheng": "ug",
+ "Shi": "ui",
+ "Shou": "ub",
+ "Shu": "uu",
+ "Shua": "uw",
+ "Shuai": "uy",
+ "Shuan": "ur",
+ "Shuang": "ud",
+ "Shui": "uv",
+ "Shun": "up",
+ "Shuo": "uo",
+ "Si": "si",
+ "Song": "ss",
+ "Sou": "sb",
+ "Su": "su",
+ "Suan": "sr",
+ "Sui": "sv",
+ "Sun": "sp",
+ "Suo": "so",
+ "Ta": "ta",
+ "Tai": "tl",
+ "Tan": "tj",
+ "Tang": "th",
+ "Tao": "tk",
+ "Te": "te",
+ "Tei": "tz",
+ "Teng": "tg",
+ "Ti": "ti",
+ "Tian": "tm",
+ "Tiao": "tc",
+ "Tie": "tx",
+ "Ting": "ty",
+ "Tong": "ts",
+ "Tou": "tb",
+ "Tu": "tu",
+ "Tuan": "tr",
+ "Tui": "tv",
+ "Tun": "tp",
+ "Tuo": "to",
+ "Xi": "xi",
+ "Xia": "xw",
+ "Xian": "xm",
+ "Xiang": "xd",
+ "Xiao": "xc",
+ "Xie": "xx",
+ "Xin": "xn",
+ "Xing": "xy",
+ "Xiong": "xs",
+ "Xiu": "xq",
+ "Xu": "xu",
+ "Xuan": "xr",
+ "Xue": "xt",
+ "Xun": "xp",
+ "Za": "za",
+ "Zai": "zl",
+ "Zan": "zj",
+ "Zang": "zh",
+ "Zao": "zk",
+ "Ze": "ze",
+ "Zei": "zz",
+ "Zen": "zf",
+ "Zeng": "zg",
+ "Zha": "va",
+ "Zhai": "vl",
+ "Zhan": "vj",
+ "Zhang": "vh",
+ "Zhao": "vk",
+ "Zhe": "ve",
+ "Zhen": "vf",
+ "Zheng": "vg",
+ "Zhi": "vi",
+ "Zhong": "vs",
+ "Zhou": "vb",
+ "Zhu": "vu",
+ "Zhua": "vw",
+ "Zhuai": "vy",
+ "Zhuan": "vr",
+ "Zhuang": "vd",
+ "Zhui": "vv",
+ "Zhun": "vp",
+ "Zhuo": "vo",
+ "Zi": "zi",
+ "Zong": "zs",
+ "Zou": "zb",
+ "Zu": "zu",
+ "Zuan": "zr",
+ "Zui": "zv",
+ "Zun": "zp",
+ "Zuo": "zo"
+ },
+ "WeiRuan": {
+ "Lv": "ly",
+ "Lve": "lt",
+ "Lue": "lt",
+ "Nv": "ny",
+ "Nve": "nt",
+ "Nue": "nt",
+ "A": "oa",
+ "O": "oo",
+ "E": "oe",
+ "Ai": "ol",
+ "Ei": "oz",
+ "Ao": "ok",
+ "Ou": "ob",
+ "An": "oj",
+ "En": "of",
+ "Ang": "oh",
+ "Eng": "og",
+ "Er": "or",
+ "Yi": "yi",
+ "Ya": "ya",
+ "Yo": "yo",
+ "Ye": "ye",
+ "Yao": "yk",
+ "You": "yb",
+ "Yan": "yj",
+ "Yin": "yn",
+ "Yang": "yh",
+ "Ying": "y;",
+ "Wu": "wu",
+ "Wa": "wa",
+ "Wo": "wo",
+ "Wai": "wl",
+ "Wei": "wz",
+ "Wan": "wj",
+ "Wen": "wf",
+ "Wang": "wh",
+ "Weng": "wg",
+ "Yu": "yu",
+ "Yue": "yt",
+ "Yuan": "yr",
+ "Yun": "yp",
+ "Yong": "ys",
+ "Ba": "ba",
+ "Bai": "bl",
+ "Ban": "bj",
+ "Bang": "bh",
+ "Bao": "bk",
+ "Bei": "bz",
+ "Ben": "bf",
+ "Beng": "bg",
+ "Bi": "bi",
+ "Bian": "bm",
+ "Biang": "bd",
+ "Biao": "bc",
+ "Bie": "bx",
+ "Bin": "bn",
+ "Bing": "b;",
+ "Bo": "bo",
+ "Bu": "bu",
+ "Ca": "ca",
+ "Cai": "cl",
+ "Can": "cj",
+ "Cang": "ch",
+ "Cao": "ck",
+ "Ce": "ce",
+ "Cen": "cf",
+ "Ceng": "cg",
+ "Cha": "ia",
+ "Chai": "il",
+ "Chan": "ij",
+ "Chang": "ih",
+ "Chao": "ik",
+ "Che": "ie",
+ "Chen": "if",
+ "Cheng": "ig",
+ "Chi": "ii",
+ "Chong": "is",
+ "Chou": "ib",
+ "Chu": "iu",
+ "Chua": "iw",
+ "Chuai": "iy",
+ "Chuan": "ir",
+ "Chuang": "id",
+ "Chui": "iv",
+ "Chun": "ip",
+ "Chuo": "io",
+ "Ci": "ci",
+ "Cong": "cs",
+ "Cou": "cb",
+ "Cu": "cu",
+ "Cuan": "cr",
+ "Cui": "cv",
+ "Cun": "cp",
+ "Cuo": "co",
+ "Da": "da",
+ "Dai": "dl",
+ "Dan": "dj",
+ "Dang": "dh",
+ "Dao": "dk",
+ "De": "de",
+ "Dei": "dz",
+ "Den": "df",
+ "Deng": "dg",
+ "Di": "di",
+ "Dia": "dw",
+ "Dian": "dm",
+ "Diao": "dc",
+ "Die": "dx",
+ "Ding": "d;",
+ "Diu": "dq",
+ "Dong": "ds",
+ "Dou": "db",
+ "Du": "du",
+ "Duan": "dr",
+ "Dui": "dv",
+ "Dun": "dp",
+ "Duo": "do",
+ "Fa": "fa",
+ "Fan": "fj",
+ "Fang": "fh",
+ "Fei": "fz",
+ "Fen": "ff",
+ "Feng": "fg",
+ "Fiao": "fc",
+ "Fo": "fo",
+ "Fou": "fb",
+ "Fu": "fu",
+ "Ga": "ga",
+ "Gai": "gl",
+ "Gan": "gj",
+ "Gang": "gh",
+ "Gao": "gk",
+ "Ge": "ge",
+ "Gei": "gz",
+ "Gen": "gf",
+ "Geng": "gg",
+ "Gong": "gs",
+ "Gou": "gb",
+ "Gu": "gu",
+ "Gua": "gw",
+ "Guai": "gy",
+ "Guan": "gr",
+ "Guang": "gd",
+ "Gui": "gv",
+ "Gun": "gp",
+ "Guo": "go",
+ "Ha": "ha",
+ "Hai": "hl",
+ "Han": "hj",
+ "Hang": "hh",
+ "Hao": "hk",
+ "He": "he",
+ "Hei": "hz",
+ "Hen": "hf",
+ "Heng": "hg",
+ "Hong": "hs",
+ "Hou": "hb",
+ "Hu": "hu",
+ "Hua": "hw",
+ "Huai": "hy",
+ "Huan": "hr",
+ "Huang": "hd",
+ "Hui": "hv",
+ "Hun": "hp",
+ "Huo": "ho",
+ "Ji": "ji",
+ "Jia": "jw",
+ "Jian": "jm",
+ "Jiang": "jd",
+ "Jiao": "jc",
+ "Jie": "jx",
+ "Jin": "jn",
+ "Jing": "j;",
+ "Jiong": "js",
+ "Jiu": "jq",
+ "Ju": "ju",
+ "Juan": "jr",
+ "Jue": "jt",
+ "Jun": "jp",
+ "Ka": "ka",
+ "Kai": "kl",
+ "Kan": "kj",
+ "Kang": "kh",
+ "Kao": "kk",
+ "Ke": "ke",
+ "Ken": "kf",
+ "Keng": "kg",
+ "Kong": "ks",
+ "Kou": "kb",
+ "Ku": "ku",
+ "Kua": "kw",
+ "Kuai": "ky",
+ "Kuan": "kr",
+ "Kuang": "kd",
+ "Kui": "kv",
+ "Kun": "kp",
+ "Kuo": "ko",
+ "La": "la",
+ "Lai": "ll",
+ "Lan": "lj",
+ "Lang": "lh",
+ "Lao": "lk",
+ "Le": "le",
+ "Lei": "lz",
+ "Leng": "lg",
+ "Li": "li",
+ "Lia": "lw",
+ "Lian": "lm",
+ "Liang": "ld",
+ "Liao": "lc",
+ "Lie": "lx",
+ "Lin": "ln",
+ "Ling": "l;",
+ "Liu": "lq",
+ "Lo": "lo",
+ "Long": "ls",
+ "Lou": "lb",
+ "Lu": "lu",
+ "Luan": "lr",
+ "Lun": "lp",
+ "Luo": "lo",
+ "Ma": "ma",
+ "Mai": "ml",
+ "Man": "mj",
+ "Mang": "mh",
+ "Mao": "mk",
+ "Me": "me",
+ "Mei": "mz",
+ "Men": "mf",
+ "Meng": "mg",
+ "Mi": "mi",
+ "Mian": "mm",
+ "Miao": "mc",
+ "Mie": "mx",
+ "Min": "mn",
+ "Ming": "m;",
+ "Miu": "mq",
+ "Mo": "mo",
+ "Mou": "mb",
+ "Mu": "mu",
+ "Na": "na",
+ "Nai": "nl",
+ "Nan": "nj",
+ "Nang": "nh",
+ "Nao": "nk",
+ "Ne": "ne",
+ "Nei": "nz",
+ "Nen": "nf",
+ "Neng": "ng",
+ "Ni": "ni",
+ "Nian": "nm",
+ "Niang": "nd",
+ "Niao": "nc",
+ "Nie": "nx",
+ "Nin": "nn",
+ "Ning": "n;",
+ "Niu": "nq",
+ "Nong": "ns",
+ "Nou": "nb",
+ "Nu": "nu",
+ "Nuan": "nr",
+ "Nun": "np",
+ "Nuo": "no",
+ "Pa": "pa",
+ "Pai": "pl",
+ "Pan": "pj",
+ "Pang": "ph",
+ "Pao": "pk",
+ "Pei": "pz",
+ "Pen": "pf",
+ "Peng": "pg",
+ "Pi": "pi",
+ "Pian": "pm",
+ "Piao": "pc",
+ "Pie": "px",
+ "Pin": "pn",
+ "Ping": "p;",
+ "Po": "po",
+ "Pou": "pb",
+ "Pu": "pu",
+ "Qi": "qi",
+ "Qia": "qw",
+ "Qian": "qm",
+ "Qiang": "qd",
+ "Qiao": "qc",
+ "Qie": "qx",
+ "Qin": "qn",
+ "Qing": "q;",
+ "Qiong": "qs",
+ "Qiu": "qq",
+ "Qu": "qu",
+ "Quan": "qr",
+ "Que": "qt",
+ "Qun": "qp",
+ "Ran": "rj",
+ "Rang": "rh",
+ "Rao": "rk",
+ "Re": "re",
+ "Ren": "rf",
+ "Reng": "rg",
+ "Ri": "ri",
+ "Rong": "rs",
+ "Rou": "rb",
+ "Ru": "ru",
+ "Rua": "rw",
+ "Ruan": "rr",
+ "Rui": "rv",
+ "Run": "rp",
+ "Ruo": "ro",
+ "Sa": "sa",
+ "Sai": "sl",
+ "San": "sj",
+ "Sang": "sh",
+ "Sao": "sk",
+ "Se": "se",
+ "Sen": "sf",
+ "Seng": "sg",
+ "Sha": "ua",
+ "Shai": "ul",
+ "Shan": "uj",
+ "Shang": "uh",
+ "Shao": "uk",
+ "She": "ue",
+ "Shei": "uz",
+ "Shen": "uf",
+ "Sheng": "ug",
+ "Shi": "ui",
+ "Shou": "ub",
+ "Shu": "uu",
+ "Shua": "uw",
+ "Shuai": "uy",
+ "Shuan": "ur",
+ "Shuang": "ud",
+ "Shui": "uv",
+ "Shun": "up",
+ "Shuo": "uo",
+ "Si": "si",
+ "Song": "ss",
+ "Sou": "sb",
+ "Su": "su",
+ "Suan": "sr",
+ "Sui": "sv",
+ "Sun": "sp",
+ "Suo": "so",
+ "Ta": "ta",
+ "Tai": "tl",
+ "Tan": "tj",
+ "Tang": "th",
+ "Tao": "tk",
+ "Te": "te",
+ "Tei": "tz",
+ "Teng": "tg",
+ "Ti": "ti",
+ "Tian": "tm",
+ "Tiao": "tc",
+ "Tie": "tx",
+ "Ting": "t;",
+ "Tong": "ts",
+ "Tou": "tb",
+ "Tu": "tu",
+ "Tuan": "tr",
+ "Tui": "tv",
+ "Tun": "tp",
+ "Tuo": "to",
+ "Xi": "xi",
+ "Xia": "xw",
+ "Xian": "xm",
+ "Xiang": "xd",
+ "Xiao": "xc",
+ "Xie": "xx",
+ "Xin": "xn",
+ "Xing": "x;",
+ "Xiong": "xs",
+ "Xiu": "xq",
+ "Xu": "xu",
+ "Xuan": "xr",
+ "Xue": "xt",
+ "Xun": "xp",
+ "Za": "za",
+ "Zai": "zl",
+ "Zan": "zj",
+ "Zang": "zh",
+ "Zao": "zk",
+ "Ze": "ze",
+ "Zei": "zz",
+ "Zen": "zf",
+ "Zeng": "zg",
+ "Zha": "va",
+ "Zhai": "vl",
+ "Zhan": "vj",
+ "Zhang": "vh",
+ "Zhao": "vk",
+ "Zhe": "ve",
+ "Zhen": "vf",
+ "Zheng": "vg",
+ "Zhi": "vi",
+ "Zhong": "vs",
+ "Zhou": "vb",
+ "Zhu": "vu",
+ "Zhua": "vw",
+ "Zhuai": "vy",
+ "Zhuan": "vr",
+ "Zhuang": "vd",
+ "Zhui": "vv",
+ "Zhun": "vp",
+ "Zhuo": "vo",
+ "Zi": "zi",
+ "Zong": "zs",
+ "Zou": "zb",
+ "Zu": "zu",
+ "Zuan": "zr",
+ "Zui": "zv",
+ "Zun": "zp",
+ "Zuo": "zo"
+ },
+ "ZhiNengABC": {
+ "Lv": "lv",
+ "Lve": "lm",
+ "Lue": "lm",
+ "Nv": "nv",
+ "Nve": "nm",
+ "Nue": "nm",
+ "A": "oa",
+ "O": "oo",
+ "E": "oe",
+ "Ai": "ol",
+ "Ei": "oq",
+ "Ao": "ok",
+ "Ou": "ob",
+ "An": "oj",
+ "En": "of",
+ "Ang": "oh",
+ "Eng": "og",
+ "Er": "or",
+ "Yi": "yi",
+ "Ya": "ya",
+ "Yo": "yo",
+ "Ye": "ye",
+ "Yao": "yk",
+ "You": "yb",
+ "Yan": "yj",
+ "Yin": "yc",
+ "Yang": "yh",
+ "Ying": "yy",
+ "Wu": "wu",
+ "Wa": "wa",
+ "Wo": "wo",
+ "Wai": "wl",
+ "Wei": "wq",
+ "Wan": "wj",
+ "Wen": "wf",
+ "Wang": "wh",
+ "Weng": "wg",
+ "Yu": "yu",
+ "Yue": "ym",
+ "Yuan": "yp",
+ "Yun": "yn",
+ "Yong": "ys",
+ "Ba": "ba",
+ "Bai": "bl",
+ "Ban": "bj",
+ "Bang": "bh",
+ "Bao": "bk",
+ "Bei": "bq",
+ "Ben": "bf",
+ "Beng": "bg",
+ "Bi": "bi",
+ "Bian": "bw",
+ "Biang": "bt",
+ "Biao": "bz",
+ "Bie": "bx",
+ "Bin": "bc",
+ "Bing": "by",
+ "Bo": "bo",
+ "Bu": "bu",
+ "Ca": "ca",
+ "Cai": "cl",
+ "Can": "cj",
+ "Cang": "ch",
+ "Cao": "ck",
+ "Ce": "ce",
+ "Cen": "cf",
+ "Ceng": "cg",
+ "Cha": "ea",
+ "Chai": "el",
+ "Chan": "ej",
+ "Chang": "eh",
+ "Chao": "ek",
+ "Che": "ee",
+ "Chen": "ef",
+ "Cheng": "eg",
+ "Chi": "ei",
+ "Chong": "es",
+ "Chou": "eb",
+ "Chu": "eu",
+ "Chua": "ed",
+ "Chuai": "ec",
+ "Chuan": "ep",
+ "Chuang": "et",
+ "Chui": "em",
+ "Chun": "en",
+ "Chuo": "eo",
+ "Ci": "ci",
+ "Cong": "cs",
+ "Cou": "cb",
+ "Cu": "cu",
+ "Cuan": "cp",
+ "Cui": "cm",
+ "Cun": "cn",
+ "Cuo": "co",
+ "Da": "da",
+ "Dai": "dl",
+ "Dan": "dj",
+ "Dang": "dh",
+ "Dao": "dk",
+ "De": "de",
+ "Dei": "dq",
+ "Den": "df",
+ "Deng": "dg",
+ "Di": "di",
+ "Dia": "dd",
+ "Dian": "dw",
+ "Diao": "dz",
+ "Die": "dx",
+ "Ding": "dy",
+ "Diu": "dr",
+ "Dong": "ds",
+ "Dou": "db",
+ "Du": "du",
+ "Duan": "dp",
+ "Dui": "dm",
+ "Dun": "dn",
+ "Duo": "do",
+ "Fa": "fa",
+ "Fan": "fj",
+ "Fang": "fh",
+ "Fei": "fq",
+ "Fen": "ff",
+ "Feng": "fg",
+ "Fiao": "fz",
+ "Fo": "fo",
+ "Fou": "fb",
+ "Fu": "fu",
+ "Ga": "ga",
+ "Gai": "gl",
+ "Gan": "gj",
+ "Gang": "gh",
+ "Gao": "gk",
+ "Ge": "ge",
+ "Gei": "gq",
+ "Gen": "gf",
+ "Geng": "gg",
+ "Gong": "gs",
+ "Gou": "gb",
+ "Gu": "gu",
+ "Gua": "gd",
+ "Guai": "gc",
+ "Guan": "gp",
+ "Guang": "gt",
+ "Gui": "gm",
+ "Gun": "gn",
+ "Guo": "go",
+ "Ha": "ha",
+ "Hai": "hl",
+ "Han": "hj",
+ "Hang": "hh",
+ "Hao": "hk",
+ "He": "he",
+ "Hei": "hq",
+ "Hen": "hf",
+ "Heng": "hg",
+ "Hong": "hs",
+ "Hou": "hb",
+ "Hu": "hu",
+ "Hua": "hd",
+ "Huai": "hc",
+ "Huan": "hp",
+ "Huang": "ht",
+ "Hui": "hm",
+ "Hun": "hn",
+ "Huo": "ho",
+ "Ji": "ji",
+ "Jia": "jd",
+ "Jian": "jw",
+ "Jiang": "jt",
+ "Jiao": "jz",
+ "Jie": "jx",
+ "Jin": "jc",
+ "Jing": "jy",
+ "Jiong": "js",
+ "Jiu": "jr",
+ "Ju": "ju",
+ "Juan": "jp",
+ "Jue": "jm",
+ "Jun": "jn",
+ "Ka": "ka",
+ "Kai": "kl",
+ "Kan": "kj",
+ "Kang": "kh",
+ "Kao": "kk",
+ "Ke": "ke",
+ "Ken": "kf",
+ "Keng": "kg",
+ "Kong": "ks",
+ "Kou": "kb",
+ "Ku": "ku",
+ "Kua": "kd",
+ "Kuai": "kc",
+ "Kuan": "kp",
+ "Kuang": "kt",
+ "Kui": "km",
+ "Kun": "kn",
+ "Kuo": "ko",
+ "La": "la",
+ "Lai": "ll",
+ "Lan": "lj",
+ "Lang": "lh",
+ "Lao": "lk",
+ "Le": "le",
+ "Lei": "lq",
+ "Leng": "lg",
+ "Li": "li",
+ "Lia": "ld",
+ "Lian": "lw",
+ "Liang": "lt",
+ "Liao": "lz",
+ "Lie": "lx",
+ "Lin": "lc",
+ "Ling": "ly",
+ "Liu": "lr",
+ "Lo": "lo",
+ "Long": "ls",
+ "Lou": "lb",
+ "Lu": "lu",
+ "Luan": "lp",
+ "Lun": "ln",
+ "Luo": "lo",
+ "Ma": "ma",
+ "Mai": "ml",
+ "Man": "mj",
+ "Mang": "mh",
+ "Mao": "mk",
+ "Me": "me",
+ "Mei": "mq",
+ "Men": "mf",
+ "Meng": "mg",
+ "Mi": "mi",
+ "Mian": "mw",
+ "Miao": "mz",
+ "Mie": "mx",
+ "Min": "mc",
+ "Ming": "my",
+ "Miu": "mr",
+ "Mo": "mo",
+ "Mou": "mb",
+ "Mu": "mu",
+ "Na": "na",
+ "Nai": "nl",
+ "Nan": "nj",
+ "Nang": "nh",
+ "Nao": "nk",
+ "Ne": "ne",
+ "Nei": "nq",
+ "Nen": "nf",
+ "Neng": "ng",
+ "Ni": "ni",
+ "Nian": "nw",
+ "Niang": "nt",
+ "Niao": "nz",
+ "Nie": "nx",
+ "Nin": "nc",
+ "Ning": "ny",
+ "Niu": "nr",
+ "Nong": "ns",
+ "Nou": "nb",
+ "Nu": "nu",
+ "Nuan": "np",
+ "Nun": "nn",
+ "Nuo": "no",
+ "Pa": "pa",
+ "Pai": "pl",
+ "Pan": "pj",
+ "Pang": "ph",
+ "Pao": "pk",
+ "Pei": "pq",
+ "Pen": "pf",
+ "Peng": "pg",
+ "Pi": "pi",
+ "Pian": "pw",
+ "Piao": "pz",
+ "Pie": "px",
+ "Pin": "pc",
+ "Ping": "py",
+ "Po": "po",
+ "Pou": "pb",
+ "Pu": "pu",
+ "Qi": "qi",
+ "Qia": "qd",
+ "Qian": "qw",
+ "Qiang": "qt",
+ "Qiao": "qz",
+ "Qie": "qx",
+ "Qin": "qc",
+ "Qing": "qy",
+ "Qiong": "qs",
+ "Qiu": "qr",
+ "Qu": "qu",
+ "Quan": "qp",
+ "Que": "qm",
+ "Qun": "qn",
+ "Ran": "rj",
+ "Rang": "rh",
+ "Rao": "rk",
+ "Re": "re",
+ "Ren": "rf",
+ "Reng": "rg",
+ "Ri": "ri",
+ "Rong": "rs",
+ "Rou": "rb",
+ "Ru": "ru",
+ "Rua": "rd",
+ "Ruan": "rp",
+ "Rui": "rm",
+ "Run": "rn",
+ "Ruo": "ro",
+ "Sa": "sa",
+ "Sai": "sl",
+ "San": "sj",
+ "Sang": "sh",
+ "Sao": "sk",
+ "Se": "se",
+ "Sen": "sf",
+ "Seng": "sg",
+ "Sha": "va",
+ "Shai": "vl",
+ "Shan": "vj",
+ "Shang": "vh",
+ "Shao": "vk",
+ "She": "ve",
+ "Shei": "vq",
+ "Shen": "vf",
+ "Sheng": "vg",
+ "Shi": "vi",
+ "Shou": "vb",
+ "Shu": "vu",
+ "Shua": "vd",
+ "Shuai": "vc",
+ "Shuan": "vp",
+ "Shuang": "vt",
+ "Shui": "vm",
+ "Shun": "vn",
+ "Shuo": "vo",
+ "Si": "si",
+ "Song": "ss",
+ "Sou": "sb",
+ "Su": "su",
+ "Suan": "sp",
+ "Sui": "sm",
+ "Sun": "sn",
+ "Suo": "so",
+ "Ta": "ta",
+ "Tai": "tl",
+ "Tan": "tj",
+ "Tang": "th",
+ "Tao": "tk",
+ "Te": "te",
+ "Tei": "tq",
+ "Teng": "tg",
+ "Ti": "ti",
+ "Tian": "tw",
+ "Tiao": "tz",
+ "Tie": "tx",
+ "Ting": "ty",
+ "Tong": "ts",
+ "Tou": "tb",
+ "Tu": "tu",
+ "Tuan": "tp",
+ "Tui": "tm",
+ "Tun": "tn",
+ "Tuo": "to",
+ "Xi": "xi",
+ "Xia": "xd",
+ "Xian": "xw",
+ "Xiang": "xt",
+ "Xiao": "xz",
+ "Xie": "xx",
+ "Xin": "xc",
+ "Xing": "xy",
+ "Xiong": "xs",
+ "Xiu": "xr",
+ "Xu": "xu",
+ "Xuan": "xp",
+ "Xue": "xm",
+ "Xun": "xn",
+ "Za": "za",
+ "Zai": "zl",
+ "Zan": "zj",
+ "Zang": "zh",
+ "Zao": "zk",
+ "Ze": "ze",
+ "Zei": "zq",
+ "Zen": "zf",
+ "Zeng": "zg",
+ "Zha": "aa",
+ "Zhai": "al",
+ "Zhan": "aj",
+ "Zhang": "ah",
+ "Zhao": "ak",
+ "Zhe": "ae",
+ "Zhen": "af",
+ "Zheng": "ag",
+ "Zhi": "ai",
+ "Zhong": "as",
+ "Zhou": "ab",
+ "Zhu": "au",
+ "Zhua": "ad",
+ "Zhuai": "ac",
+ "Zhuan": "ap",
+ "Zhuang": "at",
+ "Zhui": "am",
+ "Zhun": "an",
+ "Zhuo": "ao",
+ "Zi": "zi",
+ "Zong": "zs",
+ "Zou": "zb",
+ "Zu": "zu",
+ "Zuan": "zp",
+ "Zui": "zm",
+ "Zun": "zn",
+ "Zuo": "zo"
+ },
+ "ZiGuangPinYin": {
+ "Lv": "lv",
+ "Lve": "ln",
+ "Lue": "ln",
+ "Nv": "nv",
+ "Nve": "nn",
+ "Nue": "nn",
+ "A": "oa",
+ "O": "oo",
+ "E": "oe",
+ "Ai": "op",
+ "Ei": "ok",
+ "Ao": "oq",
+ "Ou": "oz",
+ "An": "or",
+ "En": "ow",
+ "Ang": "os",
+ "Eng": "ot",
+ "Er": "oj",
+ "Yi": "yi",
+ "Ya": "ya",
+ "Yo": "yo",
+ "Ye": "ye",
+ "Yao": "yq",
+ "You": "yz",
+ "Yan": "yr",
+ "Yin": "yy",
+ "Yang": "ys",
+ "Ying": "yc",
+ "Wu": "wu",
+ "Wa": "wa",
+ "Wo": "wo",
+ "Wai": "wp",
+ "Wei": "wk",
+ "Wan": "wr",
+ "Wen": "ww",
+ "Wang": "ws",
+ "Weng": "wt",
+ "Yu": "yu",
+ "Yue": "yn",
+ "Yuan": "yl",
+ "Yun": "ym",
+ "Yong": "yh",
+ "Ba": "ba",
+ "Bai": "bp",
+ "Ban": "br",
+ "Bang": "bs",
+ "Bao": "bq",
+ "Bei": "bk",
+ "Ben": "bw",
+ "Beng": "bt",
+ "Bi": "bi",
+ "Bian": "bf",
+ "Biang": "bg",
+ "Biao": "bb",
+ "Bie": "bd",
+ "Bin": "by",
+ "Bing": "bc",
+ "Bo": "bo",
+ "Bu": "bu",
+ "Ca": "ca",
+ "Cai": "cp",
+ "Can": "cr",
+ "Cang": "cs",
+ "Cao": "cq",
+ "Ce": "ce",
+ "Cen": "cw",
+ "Ceng": "ct",
+ "Cha": "aa",
+ "Chai": "ap",
+ "Chan": "ar",
+ "Chang": "as",
+ "Chao": "aq",
+ "Che": "ae",
+ "Chen": "aw",
+ "Cheng": "at",
+ "Chi": "ai",
+ "Chong": "ah",
+ "Chou": "az",
+ "Chu": "au",
+ "Chua": "ax",
+ "Chuai": "ay",
+ "Chuan": "al",
+ "Chuang": "ag",
+ "Chui": "an",
+ "Chun": "am",
+ "Chuo": "ao",
+ "Ci": "ci",
+ "Cong": "ch",
+ "Cou": "cz",
+ "Cu": "cu",
+ "Cuan": "cl",
+ "Cui": "cn",
+ "Cun": "cm",
+ "Cuo": "co",
+ "Da": "da",
+ "Dai": "dp",
+ "Dan": "dr",
+ "Dang": "ds",
+ "Dao": "dq",
+ "De": "de",
+ "Dei": "dk",
+ "Den": "dw",
+ "Deng": "dt",
+ "Di": "di",
+ "Dia": "dx",
+ "Dian": "df",
+ "Diao": "db",
+ "Die": "dd",
+ "Ding": "dc",
+ "Diu": "dj",
+ "Dong": "dh",
+ "Dou": "dz",
+ "Du": "du",
+ "Duan": "dl",
+ "Dui": "dn",
+ "Dun": "dm",
+ "Duo": "do",
+ "Fa": "fa",
+ "Fan": "fr",
+ "Fang": "fs",
+ "Fei": "fk",
+ "Fen": "fw",
+ "Feng": "ft",
+ "Fiao": "fb",
+ "Fo": "fo",
+ "Fou": "fz",
+ "Fu": "fu",
+ "Ga": "ga",
+ "Gai": "gp",
+ "Gan": "gr",
+ "Gang": "gs",
+ "Gao": "gq",
+ "Ge": "ge",
+ "Gei": "gk",
+ "Gen": "gw",
+ "Geng": "gt",
+ "Gong": "gh",
+ "Gou": "gz",
+ "Gu": "gu",
+ "Gua": "gx",
+ "Guai": "gy",
+ "Guan": "gl",
+ "Guang": "gg",
+ "Gui": "gn",
+ "Gun": "gm",
+ "Guo": "go",
+ "Ha": "ha",
+ "Hai": "hp",
+ "Han": "hr",
+ "Hang": "hs",
+ "Hao": "hq",
+ "He": "he",
+ "Hei": "hk",
+ "Hen": "hw",
+ "Heng": "ht",
+ "Hong": "hh",
+ "Hou": "hz",
+ "Hu": "hu",
+ "Hua": "hx",
+ "Huai": "hy",
+ "Huan": "hl",
+ "Huang": "hg",
+ "Hui": "hn",
+ "Hun": "hm",
+ "Huo": "ho",
+ "Ji": "ji",
+ "Jia": "jx",
+ "Jian": "jf",
+ "Jiang": "jg",
+ "Jiao": "jb",
+ "Jie": "jd",
+ "Jin": "jy",
+ "Jing": "jc",
+ "Jiong": "jh",
+ "Jiu": "jj",
+ "Ju": "ju",
+ "Juan": "jl",
+ "Jue": "jn",
+ "Jun": "jm",
+ "Ka": "ka",
+ "Kai": "kp",
+ "Kan": "kr",
+ "Kang": "ks",
+ "Kao": "kq",
+ "Ke": "ke",
+ "Ken": "kw",
+ "Keng": "kt",
+ "Kong": "kh",
+ "Kou": "kz",
+ "Ku": "ku",
+ "Kua": "kx",
+ "Kuai": "ky",
+ "Kuan": "kl",
+ "Kuang": "kg",
+ "Kui": "kn",
+ "Kun": "km",
+ "Kuo": "ko",
+ "La": "la",
+ "Lai": "lp",
+ "Lan": "lr",
+ "Lang": "ls",
+ "Lao": "lq",
+ "Le": "le",
+ "Lei": "lk",
+ "Leng": "lt",
+ "Li": "li",
+ "Lia": "lx",
+ "Lian": "lf",
+ "Liang": "lg",
+ "Liao": "lb",
+ "Lie": "ld",
+ "Lin": "ly",
+ "Ling": "lc",
+ "Liu": "lj",
+ "Lo": "lo",
+ "Long": "lh",
+ "Lou": "lz",
+ "Lu": "lu",
+ "Luan": "ll",
+ "Lun": "lm",
+ "Luo": "lo",
+ "Ma": "ma",
+ "Mai": "mp",
+ "Man": "mr",
+ "Mang": "ms",
+ "Mao": "mq",
+ "Me": "me",
+ "Mei": "mk",
+ "Men": "mw",
+ "Meng": "mt",
+ "Mi": "mi",
+ "Mian": "mf",
+ "Miao": "mb",
+ "Mie": "md",
+ "Min": "my",
+ "Ming": "mc",
+ "Miu": "mj",
+ "Mo": "mo",
+ "Mou": "mz",
+ "Mu": "mu",
+ "Na": "na",
+ "Nai": "np",
+ "Nan": "nr",
+ "Nang": "ns",
+ "Nao": "nq",
+ "Ne": "ne",
+ "Nei": "nk",
+ "Nen": "nw",
+ "Neng": "nt",
+ "Ni": "ni",
+ "Nian": "nf",
+ "Niang": "ng",
+ "Niao": "nb",
+ "Nie": "nd",
+ "Nin": "ny",
+ "Ning": "nc",
+ "Niu": "nj",
+ "Nong": "nh",
+ "Nou": "nz",
+ "Nu": "nu",
+ "Nuan": "nl",
+ "Nun": "nm",
+ "Nuo": "no",
+ "Pa": "pa",
+ "Pai": "pp",
+ "Pan": "pr",
+ "Pang": "ps",
+ "Pao": "pq",
+ "Pei": "pk",
+ "Pen": "pw",
+ "Peng": "pt",
+ "Pi": "pi",
+ "Pian": "pf",
+ "Piao": "pb",
+ "Pie": "pd",
+ "Pin": "py",
+ "Ping": "pc",
+ "Po": "po",
+ "Pou": "pz",
+ "Pu": "pu",
+ "Qi": "qi",
+ "Qia": "qx",
+ "Qian": "qf",
+ "Qiang": "qg",
+ "Qiao": "qb",
+ "Qie": "qd",
+ "Qin": "qy",
+ "Qing": "qc",
+ "Qiong": "qh",
+ "Qiu": "qj",
+ "Qu": "qu",
+ "Quan": "ql",
+ "Que": "qn",
+ "Qun": "qm",
+ "Ran": "rr",
+ "Rang": "rs",
+ "Rao": "rq",
+ "Re": "re",
+ "Ren": "rw",
+ "Reng": "rt",
+ "Ri": "ri",
+ "Rong": "rh",
+ "Rou": "rz",
+ "Ru": "ru",
+ "Rua": "rx",
+ "Ruan": "rl",
+ "Rui": "rn",
+ "Run": "rm",
+ "Ruo": "ro",
+ "Sa": "sa",
+ "Sai": "sp",
+ "San": "sr",
+ "Sang": "ss",
+ "Sao": "sq",
+ "Se": "se",
+ "Sen": "sw",
+ "Seng": "st",
+ "Sha": "ia",
+ "Shai": "ip",
+ "Shan": "ir",
+ "Shang": "is",
+ "Shao": "iq",
+ "She": "ie",
+ "Shei": "ik",
+ "Shen": "iw",
+ "Sheng": "it",
+ "Shi": "ii",
+ "Shou": "iz",
+ "Shu": "iu",
+ "Shua": "ix",
+ "Shuai": "iy",
+ "Shuan": "il",
+ "Shuang": "ig",
+ "Shui": "in",
+ "Shun": "im",
+ "Shuo": "io",
+ "Si": "si",
+ "Song": "sh",
+ "Sou": "sz",
+ "Su": "su",
+ "Suan": "sl",
+ "Sui": "sn",
+ "Sun": "sm",
+ "Suo": "so",
+ "Ta": "ta",
+ "Tai": "tp",
+ "Tan": "tr",
+ "Tang": "ts",
+ "Tao": "tq",
+ "Te": "te",
+ "Tei": "tk",
+ "Teng": "tt",
+ "Ti": "ti",
+ "Tian": "tf",
+ "Tiao": "tb",
+ "Tie": "td",
+ "Ting": "tc",
+ "Tong": "th",
+ "Tou": "tz",
+ "Tu": "tu",
+ "Tuan": "tl",
+ "Tui": "tn",
+ "Tun": "tm",
+ "Tuo": "to",
+ "Xi": "xi",
+ "Xia": "xx",
+ "Xian": "xf",
+ "Xiang": "xg",
+ "Xiao": "xb",
+ "Xie": "xd",
+ "Xin": "xy",
+ "Xing": "xc",
+ "Xiong": "xh",
+ "Xiu": "xj",
+ "Xu": "xu",
+ "Xuan": "xl",
+ "Xue": "xn",
+ "Xun": "xm",
+ "Za": "za",
+ "Zai": "zp",
+ "Zan": "zr",
+ "Zang": "zs",
+ "Zao": "zq",
+ "Ze": "ze",
+ "Zei": "zk",
+ "Zen": "zw",
+ "Zeng": "zt",
+ "Zha": "ua",
+ "Zhai": "up",
+ "Zhan": "ur",
+ "Zhang": "us",
+ "Zhao": "uq",
+ "Zhe": "ue",
+ "Zhen": "uw",
+ "Zheng": "ut",
+ "Zhi": "ui",
+ "Zhong": "uh",
+ "Zhou": "uz",
+ "Zhu": "uu",
+ "Zhua": "ux",
+ "Zhuai": "uy",
+ "Zhuan": "ul",
+ "Zhuang": "ug",
+ "Zhui": "un",
+ "Zhun": "um",
+ "Zhuo": "uo",
+ "Zi": "zi",
+ "Zong": "zh",
+ "Zou": "zz",
+ "Zu": "zu",
+ "Zuan": "zl",
+ "Zui": "zn",
+ "Zun": "zm",
+ "Zuo": "zo"
+ },
+ "PinYinJiaJia": {
+ "Lv": "lv",
+ "Lve": "lx",
+ "Lue": "lx",
+ "Nv": "nv",
+ "Nve": "nx",
+ "Nue": "nx",
+ "A": "aa",
+ "O": "oo",
+ "E": "ee",
+ "Ai": "as",
+ "Ei": "ew",
+ "Ao": "ad",
+ "Ou": "op",
+ "An": "af",
+ "En": "er",
+ "Ang": "ag",
+ "Eng": "et",
+ "Er": "eq",
+ "Yi": "yi",
+ "Ya": "ya",
+ "Yo": "yo",
+ "Ye": "ye",
+ "Yao": "yd",
+ "You": "yp",
+ "Yan": "yf",
+ "Yin": "yl",
+ "Yang": "yg",
+ "Ying": "yq",
+ "Wu": "wu",
+ "Wa": "wa",
+ "Wo": "wo",
+ "Wai": "ws",
+ "Wei": "ww",
+ "Wan": "wf",
+ "Wen": "wr",
+ "Wang": "wg",
+ "Weng": "wt",
+ "Yu": "yu",
+ "Yue": "yx",
+ "Yuan": "yc",
+ "Yun": "yz",
+ "Yong": "yy",
+ "Ba": "ba",
+ "Bai": "bs",
+ "Ban": "bf",
+ "Bang": "bg",
+ "Bao": "bd",
+ "Bei": "bw",
+ "Ben": "br",
+ "Beng": "bt",
+ "Bi": "bi",
+ "Bian": "bj",
+ "Biang": "bh",
+ "Biao": "bk",
+ "Bie": "bm",
+ "Bin": "bl",
+ "Bing": "bq",
+ "Bo": "bo",
+ "Bu": "bu",
+ "Ca": "ca",
+ "Cai": "cs",
+ "Can": "cf",
+ "Cang": "cg",
+ "Cao": "cd",
+ "Ce": "ce",
+ "Cen": "cr",
+ "Ceng": "ct",
+ "Cha": "ua",
+ "Chai": "us",
+ "Chan": "uf",
+ "Chang": "ug",
+ "Chao": "ud",
+ "Che": "ue",
+ "Chen": "ur",
+ "Cheng": "ut",
+ "Chi": "ui",
+ "Chong": "uy",
+ "Chou": "up",
+ "Chu": "uu",
+ "Chua": "ub",
+ "Chuai": "ux",
+ "Chuan": "uc",
+ "Chuang": "uh",
+ "Chui": "uv",
+ "Chun": "uz",
+ "Chuo": "uo",
+ "Ci": "ci",
+ "Cong": "cy",
+ "Cou": "cp",
+ "Cu": "cu",
+ "Cuan": "cc",
+ "Cui": "cv",
+ "Cun": "cz",
+ "Cuo": "co",
+ "Da": "da",
+ "Dai": "ds",
+ "Dan": "df",
+ "Dang": "dg",
+ "Dao": "dd",
+ "De": "de",
+ "Dei": "dw",
+ "Den": "dr",
+ "Deng": "dt",
+ "Di": "di",
+ "Dia": "db",
+ "Dian": "dj",
+ "Diao": "dk",
+ "Die": "dm",
+ "Ding": "dq",
+ "Diu": "dn",
+ "Dong": "dy",
+ "Dou": "dp",
+ "Du": "du",
+ "Duan": "dc",
+ "Dui": "dv",
+ "Dun": "dz",
+ "Duo": "do",
+ "Fa": "fa",
+ "Fan": "ff",
+ "Fang": "fg",
+ "Fei": "fw",
+ "Fen": "fr",
+ "Feng": "ft",
+ "Fiao": "fk",
+ "Fo": "fo",
+ "Fou": "fp",
+ "Fu": "fu",
+ "Ga": "ga",
+ "Gai": "gs",
+ "Gan": "gf",
+ "Gang": "gg",
+ "Gao": "gd",
+ "Ge": "ge",
+ "Gei": "gw",
+ "Gen": "gr",
+ "Geng": "gt",
+ "Gong": "gy",
+ "Gou": "gp",
+ "Gu": "gu",
+ "Gua": "gb",
+ "Guai": "gx",
+ "Guan": "gc",
+ "Guang": "gh",
+ "Gui": "gv",
+ "Gun": "gz",
+ "Guo": "go",
+ "Ha": "ha",
+ "Hai": "hs",
+ "Han": "hf",
+ "Hang": "hg",
+ "Hao": "hd",
+ "He": "he",
+ "Hei": "hw",
+ "Hen": "hr",
+ "Heng": "ht",
+ "Hong": "hy",
+ "Hou": "hp",
+ "Hu": "hu",
+ "Hua": "hb",
+ "Huai": "hx",
+ "Huan": "hc",
+ "Huang": "hh",
+ "Hui": "hv",
+ "Hun": "hz",
+ "Huo": "ho",
+ "Ji": "ji",
+ "Jia": "jb",
+ "Jian": "jj",
+ "Jiang": "jh",
+ "Jiao": "jk",
+ "Jie": "jm",
+ "Jin": "jl",
+ "Jing": "jq",
+ "Jiong": "jy",
+ "Jiu": "jn",
+ "Ju": "ju",
+ "Juan": "jc",
+ "Jue": "jx",
+ "Jun": "jz",
+ "Ka": "ka",
+ "Kai": "ks",
+ "Kan": "kf",
+ "Kang": "kg",
+ "Kao": "kd",
+ "Ke": "ke",
+ "Ken": "kr",
+ "Keng": "kt",
+ "Kong": "ky",
+ "Kou": "kp",
+ "Ku": "ku",
+ "Kua": "kb",
+ "Kuai": "kx",
+ "Kuan": "kc",
+ "Kuang": "kh",
+ "Kui": "kv",
+ "Kun": "kz",
+ "Kuo": "ko",
+ "La": "la",
+ "Lai": "ls",
+ "Lan": "lf",
+ "Lang": "lg",
+ "Lao": "ld",
+ "Le": "le",
+ "Lei": "lw",
+ "Leng": "lt",
+ "Li": "li",
+ "Lia": "lb",
+ "Lian": "lj",
+ "Liang": "lh",
+ "Liao": "lk",
+ "Lie": "lm",
+ "Lin": "ll",
+ "Ling": "lq",
+ "Liu": "ln",
+ "Lo": "lo",
+ "Long": "ly",
+ "Lou": "lp",
+ "Lu": "lu",
+ "Luan": "lc",
+ "Lun": "lz",
+ "Luo": "lo",
+ "Ma": "ma",
+ "Mai": "ms",
+ "Man": "mf",
+ "Mang": "mg",
+ "Mao": "md",
+ "Me": "me",
+ "Mei": "mw",
+ "Men": "mr",
+ "Meng": "mt",
+ "Mi": "mi",
+ "Mian": "mj",
+ "Miao": "mk",
+ "Mie": "mm",
+ "Min": "ml",
+ "Ming": "mq",
+ "Miu": "mn",
+ "Mo": "mo",
+ "Mou": "mp",
+ "Mu": "mu",
+ "Na": "na",
+ "Nai": "ns",
+ "Nan": "nf",
+ "Nang": "ng",
+ "Nao": "nd",
+ "Ne": "ne",
+ "Nei": "nw",
+ "Nen": "nr",
+ "Neng": "nt",
+ "Ni": "ni",
+ "Nian": "nj",
+ "Niang": "nh",
+ "Niao": "nk",
+ "Nie": "nm",
+ "Nin": "nl",
+ "Ning": "nq",
+ "Niu": "nn",
+ "Nong": "ny",
+ "Nou": "np",
+ "Nu": "nu",
+ "Nuan": "nc",
+ "Nun": "nz",
+ "Nuo": "no",
+ "Pa": "pa",
+ "Pai": "ps",
+ "Pan": "pf",
+ "Pang": "pg",
+ "Pao": "pd",
+ "Pei": "pw",
+ "Pen": "pr",
+ "Peng": "pt",
+ "Pi": "pi",
+ "Pian": "pj",
+ "Piao": "pk",
+ "Pie": "pm",
+ "Pin": "pl",
+ "Ping": "pq",
+ "Po": "po",
+ "Pou": "pp",
+ "Pu": "pu",
+ "Qi": "qi",
+ "Qia": "qb",
+ "Qian": "qj",
+ "Qiang": "qh",
+ "Qiao": "qk",
+ "Qie": "qm",
+ "Qin": "ql",
+ "Qing": "qq",
+ "Qiong": "qy",
+ "Qiu": "qn",
+ "Qu": "qu",
+ "Quan": "qc",
+ "Que": "qx",
+ "Qun": "qz",
+ "Ran": "rf",
+ "Rang": "rg",
+ "Rao": "rd",
+ "Re": "re",
+ "Ren": "rr",
+ "Reng": "rt",
+ "Ri": "ri",
+ "Rong": "ry",
+ "Rou": "rp",
+ "Ru": "ru",
+ "Rua": "rb",
+ "Ruan": "rc",
+ "Rui": "rv",
+ "Run": "rz",
+ "Ruo": "ro",
+ "Sa": "sa",
+ "Sai": "ss",
+ "San": "sf",
+ "Sang": "sg",
+ "Sao": "sd",
+ "Se": "se",
+ "Sen": "sr",
+ "Seng": "st",
+ "Sha": "ia",
+ "Shai": "is",
+ "Shan": "if",
+ "Shang": "ig",
+ "Shao": "id",
+ "She": "ie",
+ "Shei": "iw",
+ "Shen": "ir",
+ "Sheng": "it",
+ "Shi": "ii",
+ "Shou": "ip",
+ "Shu": "iu",
+ "Shua": "ib",
+ "Shuai": "ix",
+ "Shuan": "ic",
+ "Shuang": "ih",
+ "Shui": "iv",
+ "Shun": "iz",
+ "Shuo": "io",
+ "Si": "si",
+ "Song": "sy",
+ "Sou": "sp",
+ "Su": "su",
+ "Suan": "sc",
+ "Sui": "sv",
+ "Sun": "sz",
+ "Suo": "so",
+ "Ta": "ta",
+ "Tai": "ts",
+ "Tan": "tf",
+ "Tang": "tg",
+ "Tao": "td",
+ "Te": "te",
+ "Tei": "tw",
+ "Teng": "tt",
+ "Ti": "ti",
+ "Tian": "tj",
+ "Tiao": "tk",
+ "Tie": "tm",
+ "Ting": "tq",
+ "Tong": "ty",
+ "Tou": "tp",
+ "Tu": "tu",
+ "Tuan": "tc",
+ "Tui": "tv",
+ "Tun": "tz",
+ "Tuo": "to",
+ "Xi": "xi",
+ "Xia": "xb",
+ "Xian": "xj",
+ "Xiang": "xh",
+ "Xiao": "xk",
+ "Xie": "xm",
+ "Xin": "xl",
+ "Xing": "xq",
+ "Xiong": "xy",
+ "Xiu": "xn",
+ "Xu": "xu",
+ "Xuan": "xc",
+ "Xue": "xx",
+ "Xun": "xz",
+ "Za": "za",
+ "Zai": "zs",
+ "Zan": "zf",
+ "Zang": "zg",
+ "Zao": "zd",
+ "Ze": "ze",
+ "Zei": "zw",
+ "Zen": "zr",
+ "Zeng": "zt",
+ "Zha": "va",
+ "Zhai": "vs",
+ "Zhan": "vf",
+ "Zhang": "vg",
+ "Zhao": "vd",
+ "Zhe": "ve",
+ "Zhen": "vr",
+ "Zheng": "vt",
+ "Zhi": "vi",
+ "Zhong": "vy",
+ "Zhou": "vp",
+ "Zhu": "vu",
+ "Zhua": "vb",
+ "Zhuai": "vx",
+ "Zhuan": "vc",
+ "Zhuang": "vh",
+ "Zhui": "vv",
+ "Zhun": "vz",
+ "Zhuo": "vo",
+ "Zi": "zi",
+ "Zong": "zy",
+ "Zou": "zp",
+ "Zu": "zu",
+ "Zuan": "zc",
+ "Zui": "zv",
+ "Zun": "zz",
+ "Zuo": "zo"
+ },
+ "XingKongJianDao": {
+ "Lv": "lv",
+ "Lve": "ly",
+ "Lue": "ly",
+ "Nv": "nv",
+ "Nve": "ny",
+ "Nue": "ny",
+ "A": "xa",
+ "O": "xo",
+ "E": "xe",
+ "Ai": "xj",
+ "Ei": "xw",
+ "Ao": "xs",
+ "Ou": "xt",
+ "An": "xd",
+ "En": "xk",
+ "Ang": "xf",
+ "Eng": "xh",
+ "Er": "xu",
+ "Yi": "yi",
+ "Ya": "ya",
+ "Yo": "yo",
+ "Ye": "ye",
+ "Yao": "ys",
+ "You": "yt",
+ "Yan": "yd",
+ "Yin": "yb",
+ "Yang": "yf",
+ "Ying": "yg",
+ "Wu": "wj",
+ "Wa": "ws",
+ "Wo": "wo",
+ "Wai": "wh",
+ "Wei": "ww",
+ "Wan": "wf",
+ "Wen": "wn",
+ "Wang": "wp",
+ "Weng": "wr",
+ "Yu": "yv",
+ "Yue": "yy",
+ "Yuan": "yr",
+ "Yun": "yw",
+ "Yong": "yl",
+ "Ba": "ba",
+ "Bai": "bj",
+ "Ban": "bd",
+ "Bang": "bf",
+ "Bao": "bs",
+ "Bei": "bw",
+ "Ben": "bk",
+ "Beng": "bh",
+ "Bi": "bi",
+ "Bian": "bm",
+ "Biang": "bx",
+ "Biao": "bp",
+ "Bie": "bc",
+ "Bin": "bb",
+ "Bing": "bg",
+ "Bo": "bo",
+ "Bu": "bu",
+ "Ca": "ca",
+ "Cai": "cj",
+ "Can": "cd",
+ "Cang": "cf",
+ "Cao": "cs",
+ "Ce": "ce",
+ "Cen": "ck",
+ "Ceng": "ch",
+ "Cha": "ja",
+ "Chai": "jj",
+ "Chan": "jd",
+ "Chang": "jf",
+ "Chao": "js",
+ "Che": "je",
+ "Chen": "jk",
+ "Cheng": "jh",
+ "Chi": "wi",
+ "Chong": "wl",
+ "Chou": "jt",
+ "Chu": "ju",
+ "Chua": "wx",
+ "Chuai": "wg",
+ "Chuan": "wr",
+ "Chuang": "wn",
+ "Chui": "wy",
+ "Chun": "jz",
+ "Chuo": "jo",
+ "Ci": "ci",
+ "Cong": "cl",
+ "Cou": "ct",
+ "Cu": "cu",
+ "Cuan": "cr",
+ "Cui": "cy",
+ "Cun": "cz",
+ "Cuo": "co",
+ "Da": "da",
+ "Dai": "dj",
+ "Dan": "dd",
+ "Dang": "df",
+ "Dao": "ds",
+ "De": "de",
+ "Dei": "dw",
+ "Den": "dk",
+ "Deng": "dh",
+ "Di": "di",
+ "Dia": "dx",
+ "Dian": "dm",
+ "Diao": "dp",
+ "Die": "dc",
+ "Ding": "dg",
+ "Diu": "dq",
+ "Dong": "dl",
+ "Dou": "dt",
+ "Du": "du",
+ "Duan": "dr",
+ "Dui": "dy",
+ "Dun": "dz",
+ "Duo": "do",
+ "Fa": "fs",
+ "Fan": "ff",
+ "Fang": "fp",
+ "Fei": "fw",
+ "Fen": "fn",
+ "Feng": "fr",
+ "Fiao": "fp",
+ "Fo": "fl",
+ "Fou": "fd",
+ "Fu": "fl",
+ "Ga": "ga",
+ "Gai": "gj",
+ "Gan": "gd",
+ "Gang": "gf",
+ "Gao": "gs",
+ "Ge": "ge",
+ "Gei": "gw",
+ "Gen": "gk",
+ "Geng": "gh",
+ "Gong": "gl",
+ "Gou": "gt",
+ "Gu": "gu",
+ "Gua": "gx",
+ "Guai": "gg",
+ "Guan": "gr",
+ "Guang": "gn",
+ "Gui": "gy",
+ "Gun": "gz",
+ "Guo": "go",
+ "Ha": "ha",
+ "Hai": "hj",
+ "Han": "hd",
+ "Hang": "hf",
+ "Hao": "hs",
+ "He": "he",
+ "Hei": "hw",
+ "Hen": "hk",
+ "Heng": "hh",
+ "Hong": "hl",
+ "Hou": "ht",
+ "Hu": "hu",
+ "Hua": "hx",
+ "Huai": "hg",
+ "Huan": "hr",
+ "Huang": "hn",
+ "Hui": "hy",
+ "Hun": "hz",
+ "Huo": "ho",
+ "Ji": "jk",
+ "Jia": "js",
+ "Jian": "jm",
+ "Jiang": "jn",
+ "Jiao": "jp",
+ "Jie": "jc",
+ "Jin": "jb",
+ "Jing": "jg",
+ "Jiong": "jy",
+ "Jiu": "jq",
+ "Ju": "jv",
+ "Juan": "jt",
+ "Jue": "jh",
+ "Jun": "jw",
+ "Ka": "ka",
+ "Kai": "kj",
+ "Kan": "kd",
+ "Kang": "kf",
+ "Kao": "ks",
+ "Ke": "ke",
+ "Ken": "kk",
+ "Keng": "kh",
+ "Kong": "kl",
+ "Kou": "kt",
+ "Ku": "ku",
+ "Kua": "kx",
+ "Kuai": "kg",
+ "Kuan": "kr",
+ "Kuang": "kn",
+ "Kui": "ky",
+ "Kun": "kz",
+ "Kuo": "ko",
+ "La": "la",
+ "Lai": "lj",
+ "Lan": "ld",
+ "Lang": "lf",
+ "Lao": "ls",
+ "Le": "le",
+ "Lei": "lw",
+ "Leng": "lh",
+ "Li": "li",
+ "Lia": "lx",
+ "Lian": "lm",
+ "Liang": "ln",
+ "Liao": "lp",
+ "Lie": "lc",
+ "Lin": "lb",
+ "Ling": "lg",
+ "Liu": "lq",
+ "Lo": "ll",
+ "Long": "ll",
+ "Lou": "lt",
+ "Lu": "lu",
+ "Luan": "lr",
+ "Lun": "lz",
+ "Luo": "lo",
+ "Ma": "ma",
+ "Mai": "mj",
+ "Man": "md",
+ "Mang": "mf",
+ "Mao": "ms",
+ "Me": "me",
+ "Mei": "mw",
+ "Men": "mk",
+ "Meng": "mh",
+ "Mi": "mi",
+ "Mian": "mm",
+ "Miao": "mp",
+ "Mie": "mc",
+ "Min": "mb",
+ "Ming": "mg",
+ "Miu": "mq",
+ "Mo": "mo",
+ "Mou": "mt",
+ "Mu": "mu",
+ "Na": "na",
+ "Nai": "nj",
+ "Nan": "nd",
+ "Nang": "nf",
+ "Nao": "ns",
+ "Ne": "ne",
+ "Nei": "nw",
+ "Nen": "nk",
+ "Neng": "nh",
+ "Ni": "ni",
+ "Nian": "nm",
+ "Niang": "nn",
+ "Niao": "np",
+ "Nie": "nc",
+ "Nin": "nb",
+ "Ning": "ng",
+ "Niu": "nq",
+ "Nong": "nl",
+ "Nou": "nt",
+ "Nu": "nu",
+ "Nuan": "nr",
+ "Nun": "nz",
+ "Nuo": "no",
+ "Pa": "pa",
+ "Pai": "pj",
+ "Pan": "pd",
+ "Pang": "pf",
+ "Pao": "ps",
+ "Pei": "pw",
+ "Pen": "pk",
+ "Peng": "ph",
+ "Pi": "pi",
+ "Pian": "pm",
+ "Piao": "pp",
+ "Pie": "pc",
+ "Pin": "pb",
+ "Ping": "pg",
+ "Po": "po",
+ "Pou": "pt",
+ "Pu": "pu",
+ "Qi": "qk",
+ "Qia": "qs",
+ "Qian": "qm",
+ "Qiang": "qx",
+ "Qiao": "qp",
+ "Qie": "qc",
+ "Qin": "qb",
+ "Qing": "qg",
+ "Qiong": "qy",
+ "Qiu": "qq",
+ "Qu": "qv",
+ "Quan": "qt",
+ "Que": "qh",
+ "Qun": "qw",
+ "Ran": "rd",
+ "Rang": "rf",
+ "Rao": "rs",
+ "Re": "re",
+ "Ren": "rk",
+ "Reng": "rh",
+ "Ri": "ri",
+ "Rong": "rl",
+ "Rou": "rt",
+ "Ru": "ru",
+ "Rua": "rx",
+ "Ruan": "rr",
+ "Rui": "ry",
+ "Run": "rz",
+ "Ruo": "ro",
+ "Sa": "sa",
+ "Sai": "sj",
+ "San": "sd",
+ "Sang": "sf",
+ "Sao": "ss",
+ "Se": "se",
+ "Sen": "sk",
+ "Seng": "sh",
+ "Sha": "ea",
+ "Shai": "ej",
+ "Shan": "ed",
+ "Shang": "ef",
+ "Shao": "es",
+ "She": "ee",
+ "Shei": "ew",
+ "Shen": "ek",
+ "Sheng": "eh",
+ "Shi": "ei",
+ "Shou": "et",
+ "Shu": "eu",
+ "Shua": "ex",
+ "Shuai": "eg",
+ "Shuan": "er",
+ "Shuang": "en",
+ "Shui": "ey",
+ "Shun": "ez",
+ "Shuo": "eo",
+ "Si": "si",
+ "Song": "sl",
+ "Sou": "st",
+ "Su": "su",
+ "Suan": "sr",
+ "Sui": "sy",
+ "Sun": "sz",
+ "Suo": "so",
+ "Ta": "ta",
+ "Tai": "tj",
+ "Tan": "td",
+ "Tang": "tf",
+ "Tao": "ts",
+ "Te": "te",
+ "Tei": "tw",
+ "Teng": "th",
+ "Ti": "ti",
+ "Tian": "tm",
+ "Tiao": "tp",
+ "Tie": "tc",
+ "Ting": "tg",
+ "Tong": "tl",
+ "Tou": "tt",
+ "Tu": "tu",
+ "Tuan": "tr",
+ "Tui": "ty",
+ "Tun": "tz",
+ "Tuo": "to",
+ "Xi": "xi",
+ "Xia": "xx",
+ "Xian": "xm",
+ "Xiang": "xn",
+ "Xiao": "xp",
+ "Xie": "xc",
+ "Xin": "xb",
+ "Xing": "xg",
+ "Xiong": "xl",
+ "Xiu": "xq",
+ "Xu": "xv",
+ "Xuan": "xr",
+ "Xue": "xy",
+ "Xun": "xw",
+ "Za": "za",
+ "Zai": "zj",
+ "Zan": "zd",
+ "Zang": "zf",
+ "Zao": "zs",
+ "Ze": "ze",
+ "Zei": "zw",
+ "Zen": "zk",
+ "Zeng": "zh",
+ "Zha": "qa",
+ "Zhai": "fj",
+ "Zhan": "qd",
+ "Zhang": "qf",
+ "Zhao": "fs",
+ "Zhe": "fe",
+ "Zhen": "qk",
+ "Zheng": "qh",
+ "Zhi": "fi",
+ "Zhong": "fy",
+ "Zhou": "qt",
+ "Zhu": "qu",
+ "Zhua": "fx",
+ "Zhuai": "fg",
+ "Zhuan": "fr",
+ "Zhuang": "fn",
+ "Zhui": "fy",
+ "Zhun": "fz",
+ "Zhuo": "qo",
+ "Zi": "zi",
+ "Zong": "zl",
+ "Zou": "zt",
+ "Zu": "zu",
+ "Zuan": "zr",
+ "Zui": "zy",
+ "Zun": "zz",
+ "Zuo": "zo"
+ },
+ "DaNiu": {
+ "Lv": "lv",
+ "Lve": "lx",
+ "Lue": "lx",
+ "Nv": "nv",
+ "Nve": "nx",
+ "Nue": "nx",
+ "A": "ea",
+ "O": "eo",
+ "E": "ee",
+ "Ai": "eh",
+ "Ei": "ew",
+ "Ao": "es",
+ "Ou": "er",
+ "An": "ed",
+ "En": "ek",
+ "Ang": "ef",
+ "Eng": "ej",
+ "Er": "eu",
+ "Yi": "yi",
+ "Ya": "ya",
+ "Yo": "yo",
+ "Ye": "ye",
+ "Yao": "ys",
+ "You": "yr",
+ "Yan": "yd",
+ "Yin": "yb",
+ "Yang": "yf",
+ "Ying": "yg",
+ "Wu": "wu",
+ "Wa": "wa",
+ "Wo": "wo",
+ "Wai": "wh",
+ "Wei": "ww",
+ "Wan": "wd",
+ "Wen": "wk",
+ "Wang": "wf",
+ "Weng": "wj",
+ "Yu": "yu",
+ "Yue": "yh",
+ "Yuan": "yj",
+ "Yun": "yw",
+ "Yong": "yl",
+ "Ba": "ba",
+ "Bai": "bh",
+ "Ban": "bd",
+ "Bang": "bf",
+ "Bao": "bs",
+ "Bei": "bw",
+ "Ben": "bk",
+ "Beng": "bj",
+ "Bi": "bi",
+ "Bian": "bc",
+ "Biang": "bn",
+ "Biao": "bm",
+ "Bie": "bp",
+ "Bin": "bb",
+ "Bing": "bg",
+ "Bo": "bo",
+ "Bu": "bu",
+ "Ca": "ca",
+ "Cai": "ch",
+ "Can": "cd",
+ "Cang": "cf",
+ "Cao": "cs",
+ "Ce": "ce",
+ "Cen": "ck",
+ "Ceng": "cj",
+ "Cha": "ia",
+ "Chai": "ih",
+ "Chan": "id",
+ "Chang": "if",
+ "Chao": "is",
+ "Che": "ie",
+ "Chen": "ik",
+ "Cheng": "ij",
+ "Chi": "ii",
+ "Chong": "il",
+ "Chou": "ir",
+ "Chu": "iu",
+ "Chua": "iq",
+ "Chuai": "ig",
+ "Chuan": "iz",
+ "Chuang": "ix",
+ "Chui": "in",
+ "Chun": "iy",
+ "Chuo": "io",
+ "Ci": "ci",
+ "Cong": "cl",
+ "Cou": "cr",
+ "Cu": "cu",
+ "Cuan": "cz",
+ "Cui": "cn",
+ "Cun": "cy",
+ "Cuo": "co",
+ "Da": "da",
+ "Dai": "dh",
+ "Dan": "dd",
+ "Dang": "df",
+ "Dao": "ds",
+ "De": "de",
+ "Dei": "dw",
+ "Den": "dk",
+ "Deng": "dj",
+ "Di": "di",
+ "Dia": "dk",
+ "Dian": "dc",
+ "Diao": "dm",
+ "Die": "dp",
+ "Ding": "dg",
+ "Diu": "dt",
+ "Dong": "dl",
+ "Dou": "dr",
+ "Du": "du",
+ "Duan": "dz",
+ "Dui": "dn",
+ "Dun": "dy",
+ "Duo": "do",
+ "Fa": "fa",
+ "Fan": "fd",
+ "Fang": "ff",
+ "Fei": "fw",
+ "Fen": "fk",
+ "Feng": "fj",
+ "Fiao": "fm",
+ "Fo": "fo",
+ "Fou": "fr",
+ "Fu": "fu",
+ "Ga": "ga",
+ "Gai": "gh",
+ "Gan": "gd",
+ "Gang": "gf",
+ "Gao": "gs",
+ "Ge": "ge",
+ "Gei": "gw",
+ "Gen": "gk",
+ "Geng": "gj",
+ "Gong": "gl",
+ "Gou": "gr",
+ "Gu": "gu",
+ "Gua": "gq",
+ "Guai": "gg",
+ "Guan": "gz",
+ "Guang": "gx",
+ "Gui": "gn",
+ "Gun": "gy",
+ "Guo": "go",
+ "Ha": "ha",
+ "Hai": "hh",
+ "Han": "hd",
+ "Hang": "hf",
+ "Hao": "hs",
+ "He": "he",
+ "Hei": "hw",
+ "Hen": "hk",
+ "Heng": "hj",
+ "Hong": "hl",
+ "Hou": "hr",
+ "Hu": "hu",
+ "Hua": "hq",
+ "Huai": "hg",
+ "Huan": "hz",
+ "Huang": "hx",
+ "Hui": "hn",
+ "Hun": "hy",
+ "Huo": "ho",
+ "Ji": "ji",
+ "Jia": "jk",
+ "Jian": "jc",
+ "Jiang": "jn",
+ "Jiao": "jm",
+ "Jie": "jp",
+ "Jin": "jb",
+ "Jing": "jg",
+ "Jiong": "jl",
+ "Jiu": "jt",
+ "Ju": "ju",
+ "Juan": "jj",
+ "Jue": "jh",
+ "Jun": "jw",
+ "Ka": "ka",
+ "Kai": "kh",
+ "Kan": "kd",
+ "Kang": "kf",
+ "Kao": "ks",
+ "Ke": "ke",
+ "Ken": "kk",
+ "Keng": "kj",
+ "Kong": "kl",
+ "Kou": "kr",
+ "Ku": "ku",
+ "Kua": "kq",
+ "Kuai": "kg",
+ "Kuan": "kz",
+ "Kuang": "kx",
+ "Kui": "kn",
+ "Kun": "ky",
+ "Kuo": "ko",
+ "La": "la",
+ "Lai": "lh",
+ "Lan": "ld",
+ "Lang": "lf",
+ "Lao": "ls",
+ "Le": "le",
+ "Lei": "lw",
+ "Leng": "lj",
+ "Li": "li",
+ "Lia": "lk",
+ "Lian": "lc",
+ "Liang": "ln",
+ "Liao": "lm",
+ "Lie": "lp",
+ "Lin": "lb",
+ "Ling": "lg",
+ "Liu": "lt",
+ "Lo": "lo",
+ "Long": "ll",
+ "Lou": "lr",
+ "Lu": "lu",
+ "Luan": "lz",
+ "Lun": "ly",
+ "Luo": "lo",
+ "Ma": "ma",
+ "Mai": "mh",
+ "Man": "md",
+ "Mang": "mf",
+ "Mao": "ms",
+ "Me": "me",
+ "Mei": "mw",
+ "Men": "mk",
+ "Meng": "mj",
+ "Mi": "mi",
+ "Mian": "mc",
+ "Miao": "mm",
+ "Mie": "mp",
+ "Min": "mb",
+ "Ming": "mg",
+ "Miu": "mt",
+ "Mo": "mo",
+ "Mou": "mr",
+ "Mu": "mu",
+ "Na": "na",
+ "Nai": "nh",
+ "Nan": "nd",
+ "Nang": "nf",
+ "Nao": "ns",
+ "Ne": "ne",
+ "Nei": "nw",
+ "Nen": "nk",
+ "Neng": "nj",
+ "Ni": "ni",
+ "Nian": "nc",
+ "Niang": "nn",
+ "Niao": "nm",
+ "Nie": "np",
+ "Nin": "nb",
+ "Ning": "ng",
+ "Niu": "nt",
+ "Nong": "nl",
+ "Nou": "nr",
+ "Nu": "nu",
+ "Nuan": "nz",
+ "Nun": "ny",
+ "Nuo": "no",
+ "Pa": "pa",
+ "Pai": "ph",
+ "Pan": "pd",
+ "Pang": "pf",
+ "Pao": "ps",
+ "Pei": "pw",
+ "Pen": "pk",
+ "Peng": "pj",
+ "Pi": "pi",
+ "Pian": "pc",
+ "Piao": "pm",
+ "Pie": "pp",
+ "Pin": "pb",
+ "Ping": "pg",
+ "Po": "po",
+ "Pou": "pr",
+ "Pu": "pu",
+ "Qi": "qi",
+ "Qia": "qk",
+ "Qian": "qc",
+ "Qiang": "qn",
+ "Qiao": "qm",
+ "Qie": "qp",
+ "Qin": "qb",
+ "Qing": "qg",
+ "Qiong": "ql",
+ "Qiu": "qt",
+ "Qu": "qu",
+ "Quan": "qj",
+ "Que": "qh",
+ "Qun": "qw",
+ "Ran": "rd",
+ "Rang": "rf",
+ "Rao": "rs",
+ "Re": "re",
+ "Ren": "rk",
+ "Reng": "rj",
+ "Ri": "ri",
+ "Rong": "rl",
+ "Rou": "rr",
+ "Ru": "ru",
+ "Rua": "rq",
+ "Ruan": "rz",
+ "Rui": "rn",
+ "Run": "ry",
+ "Ruo": "ro",
+ "Sa": "sa",
+ "Sai": "sh",
+ "San": "sd",
+ "Sang": "sf",
+ "Sao": "ss",
+ "Se": "se",
+ "Sen": "sk",
+ "Seng": "sj",
+ "Sha": "ua",
+ "Shai": "uh",
+ "Shan": "ud",
+ "Shang": "uf",
+ "Shao": "us",
+ "She": "ue",
+ "Shei": "uw",
+ "Shen": "uk",
+ "Sheng": "uj",
+ "Shi": "ui",
+ "Shou": "ur",
+ "Shu": "uu",
+ "Shua": "uq",
+ "Shuai": "ug",
+ "Shuan": "uz",
+ "Shuang": "ux",
+ "Shui": "un",
+ "Shun": "uy",
+ "Shuo": "uo",
+ "Si": "si",
+ "Song": "sl",
+ "Sou": "sr",
+ "Su": "su",
+ "Suan": "sz",
+ "Sui": "sn",
+ "Sun": "sy",
+ "Suo": "so",
+ "Ta": "ta",
+ "Tai": "th",
+ "Tan": "td",
+ "Tang": "tf",
+ "Tao": "ts",
+ "Te": "te",
+ "Tei": "tw",
+ "Teng": "tj",
+ "Ti": "ti",
+ "Tian": "tc",
+ "Tiao": "tm",
+ "Tie": "tp",
+ "Ting": "tg",
+ "Tong": "tl",
+ "Tou": "tr",
+ "Tu": "tu",
+ "Tuan": "tz",
+ "Tui": "tn",
+ "Tun": "ty",
+ "Tuo": "to",
+ "Xi": "xi",
+ "Xia": "xk",
+ "Xian": "xc",
+ "Xiang": "xn",
+ "Xiao": "xm",
+ "Xie": "xp",
+ "Xin": "xb",
+ "Xing": "xg",
+ "Xiong": "xl",
+ "Xiu": "xt",
+ "Xu": "xu",
+ "Xuan": "xj",
+ "Xue": "xh",
+ "Xun": "xw",
+ "Za": "za",
+ "Zai": "zh",
+ "Zan": "zd",
+ "Zang": "zf",
+ "Zao": "zs",
+ "Ze": "ze",
+ "Zei": "zw",
+ "Zen": "zk",
+ "Zeng": "zj",
+ "Zha": "aa",
+ "Zhai": "ah",
+ "Zhan": "ad",
+ "Zhang": "af",
+ "Zhao": "as",
+ "Zhe": "ae",
+ "Zhen": "ak",
+ "Zheng": "aj",
+ "Zhi": "ai",
+ "Zhong": "al",
+ "Zhou": "ar",
+ "Zhu": "au",
+ "Zhua": "aq",
+ "Zhuai": "ag",
+ "Zhuan": "az",
+ "Zhuang": "ax",
+ "Zhui": "an",
+ "Zhun": "ay",
+ "Zhuo": "ao",
+ "Zi": "zi",
+ "Zong": "zl",
+ "Zou": "zr",
+ "Zu": "zu",
+ "Zuan": "zz",
+ "Zui": "zn",
+ "Zun": "zy",
+ "Zuo": "zo"
+ },
+ "XiaoLang": {
+ "Lv": "lx",
+ "Lve": "lb",
+ "Lue": "lb",
+ "Nv": "nx",
+ "Nve": "nb",
+ "Nue": "nb",
+ "A": "aa",
+ "O": "oo",
+ "E": "uu",
+ "Ai": "ai",
+ "Ei": "ui",
+ "Ao": "ao",
+ "Ou": "ou",
+ "An": "an",
+ "En": "un",
+ "Ang": "ah",
+ "Eng": "un",
+ "Er": "ur",
+ "Yi": "yi",
+ "Ya": "ya",
+ "Yo": "yo",
+ "Ye": "ye",
+ "Yao": "ys",
+ "You": "yr",
+ "Yan": "yj",
+ "Yin": "yd",
+ "Yang": "yh",
+ "Ying": "yv",
+ "Wu": "wu",
+ "Wa": "wa",
+ "Wo": "wo",
+ "Wai": "wk",
+ "Wei": "ww",
+ "Wan": "wj",
+ "Wen": "wm",
+ "Wang": "wh",
+ "Weng": "wn",
+ "Yu": "yu",
+ "Yue": "yb",
+ "Yuan": "yg",
+ "Yun": "yy",
+ "Yong": "yl",
+ "Ba": "ba",
+ "Bai": "bk",
+ "Ban": "bj",
+ "Bang": "bh",
+ "Bao": "bs",
+ "Bei": "bw",
+ "Ben": "bm",
+ "Beng": "bn",
+ "Bi": "bi",
+ "Bian": "bf",
+ "Biang": "bm",
+ "Biao": "bc",
+ "Bie": "bp",
+ "Bin": "bd",
+ "Bing": "bv",
+ "Bo": "bo",
+ "Bu": "bu",
+ "Ca": "ca",
+ "Cai": "ck",
+ "Can": "cj",
+ "Cang": "ch",
+ "Cao": "cs",
+ "Ce": "ce",
+ "Cen": "cm",
+ "Ceng": "cn",
+ "Cha": "ia",
+ "Chai": "ik",
+ "Chan": "ij",
+ "Chang": "ih",
+ "Chao": "is",
+ "Che": "ie",
+ "Chen": "im",
+ "Cheng": "in",
+ "Chi": "ii",
+ "Chong": "il",
+ "Chou": "ir",
+ "Chu": "iu",
+ "Chua": "if",
+ "Chuai": "iv",
+ "Chuan": "ig",
+ "Chuang": "iz",
+ "Chui": "id",
+ "Chun": "iy",
+ "Chuo": "io",
+ "Ci": "ci",
+ "Cong": "cl",
+ "Cou": "cr",
+ "Cu": "cu",
+ "Cuan": "cg",
+ "Cui": "cd",
+ "Cun": "cy",
+ "Cuo": "co",
+ "Da": "da",
+ "Dai": "dk",
+ "Dan": "dj",
+ "Dang": "dh",
+ "Dao": "ds",
+ "De": "de",
+ "Dei": "dw",
+ "Den": "dm",
+ "Deng": "dn",
+ "Di": "di",
+ "Dia": "dk",
+ "Dian": "df",
+ "Diao": "dc",
+ "Die": "dp",
+ "Ding": "dv",
+ "Diu": "dt",
+ "Dong": "dl",
+ "Dou": "dr",
+ "Du": "du",
+ "Duan": "dg",
+ "Dui": "dd",
+ "Dun": "dy",
+ "Duo": "do",
+ "Fa": "fa",
+ "Fan": "fj",
+ "Fang": "fh",
+ "Fei": "fw",
+ "Fen": "fm",
+ "Feng": "fn",
+ "Fiao": "fc",
+ "Fo": "fo",
+ "Fou": "fr",
+ "Fu": "fu",
+ "Ga": "ga",
+ "Gai": "gk",
+ "Gan": "gj",
+ "Gang": "gh",
+ "Gao": "gs",
+ "Ge": "ge",
+ "Gei": "gw",
+ "Gen": "gm",
+ "Geng": "gn",
+ "Gong": "gl",
+ "Gou": "gr",
+ "Gu": "gu",
+ "Gua": "gf",
+ "Guai": "gv",
+ "Guan": "gg",
+ "Guang": "gz",
+ "Gui": "gd",
+ "Gun": "gy",
+ "Guo": "go",
+ "Ha": "ha",
+ "Hai": "hk",
+ "Han": "hj",
+ "Hang": "hh",
+ "Hao": "hs",
+ "He": "he",
+ "Hei": "hw",
+ "Hen": "hm",
+ "Heng": "hn",
+ "Hong": "hl",
+ "Hou": "hr",
+ "Hu": "hu",
+ "Hua": "hf",
+ "Huai": "hv",
+ "Huan": "hg",
+ "Huang": "hz",
+ "Hui": "hd",
+ "Hun": "hy",
+ "Huo": "ho",
+ "Ji": "ji",
+ "Jia": "jk",
+ "Jian": "jf",
+ "Jiang": "jm",
+ "Jiao": "jc",
+ "Jie": "jp",
+ "Jin": "jd",
+ "Jing": "jv",
+ "Jiong": "jj",
+ "Jiu": "jt",
+ "Ju": "ju",
+ "Juan": "jg",
+ "Jue": "jb",
+ "Jun": "jy",
+ "Ka": "ka",
+ "Kai": "kk",
+ "Kan": "kj",
+ "Kang": "kh",
+ "Kao": "ks",
+ "Ke": "ke",
+ "Ken": "km",
+ "Keng": "kn",
+ "Kong": "kl",
+ "Kou": "kr",
+ "Ku": "ku",
+ "Kua": "kf",
+ "Kuai": "kv",
+ "Kuan": "kg",
+ "Kuang": "kz",
+ "Kui": "kd",
+ "Kun": "ky",
+ "Kuo": "ko",
+ "La": "la",
+ "Lai": "lk",
+ "Lan": "lj",
+ "Lang": "lh",
+ "Lao": "ls",
+ "Le": "le",
+ "Lei": "lw",
+ "Leng": "ln",
+ "Li": "li",
+ "Lia": "lk",
+ "Lian": "lf",
+ "Liang": "lm",
+ "Liao": "lc",
+ "Lie": "lp",
+ "Lin": "ld",
+ "Ling": "lv",
+ "Liu": "lt",
+ "Lo": "lo",
+ "Long": "ll",
+ "Lou": "lr",
+ "Lu": "lu",
+ "Luan": "lg",
+ "Lun": "ly",
+ "Luo": "lo",
+ "Ma": "ma",
+ "Mai": "mk",
+ "Man": "mj",
+ "Mang": "mh",
+ "Mao": "ms",
+ "Me": "me",
+ "Mei": "mw",
+ "Men": "mm",
+ "Meng": "mn",
+ "Mi": "mi",
+ "Mian": "mf",
+ "Miao": "mc",
+ "Mie": "mp",
+ "Min": "md",
+ "Ming": "mv",
+ "Miu": "mt",
+ "Mo": "mo",
+ "Mou": "mr",
+ "Mu": "mu",
+ "Na": "na",
+ "Nai": "nk",
+ "Nan": "nj",
+ "Nang": "nh",
+ "Nao": "ns",
+ "Ne": "ne",
+ "Nei": "nw",
+ "Nen": "nm",
+ "Neng": "nn",
+ "Ni": "ni",
+ "Nian": "nf",
+ "Niang": "nm",
+ "Niao": "nc",
+ "Nie": "np",
+ "Nin": "nd",
+ "Ning": "nv",
+ "Niu": "nt",
+ "Nong": "nl",
+ "Nou": "nr",
+ "Nu": "nu",
+ "Nuan": "ng",
+ "Nun": "ny",
+ "Nuo": "no",
+ "Pa": "pa",
+ "Pai": "pk",
+ "Pan": "pj",
+ "Pang": "ph",
+ "Pao": "ps",
+ "Pei": "pw",
+ "Pen": "pm",
+ "Peng": "pn",
+ "Pi": "pi",
+ "Pian": "pf",
+ "Piao": "pc",
+ "Pie": "pp",
+ "Pin": "pd",
+ "Ping": "pv",
+ "Po": "po",
+ "Pou": "pr",
+ "Pu": "pu",
+ "Qi": "qi",
+ "Qia": "qk",
+ "Qian": "qf",
+ "Qiang": "qm",
+ "Qiao": "qc",
+ "Qie": "qp",
+ "Qin": "qd",
+ "Qing": "qv",
+ "Qiong": "qj",
+ "Qiu": "qt",
+ "Qu": "qu",
+ "Quan": "qg",
+ "Que": "qb",
+ "Qun": "qy",
+ "Ran": "rj",
+ "Rang": "rh",
+ "Rao": "rs",
+ "Re": "re",
+ "Ren": "rm",
+ "Reng": "rn",
+ "Ri": "ri",
+ "Rong": "rl",
+ "Rou": "rr",
+ "Ru": "ru",
+ "Rua": "rf",
+ "Ruan": "rg",
+ "Rui": "rd",
+ "Run": "ry",
+ "Ruo": "ro",
+ "Sa": "sa",
+ "Sai": "sk",
+ "San": "sj",
+ "Sang": "sh",
+ "Sao": "ss",
+ "Se": "se",
+ "Sen": "sm",
+ "Seng": "sn",
+ "Sha": "va",
+ "Shai": "vk",
+ "Shan": "vj",
+ "Shang": "vh",
+ "Shao": "vs",
+ "She": "ve",
+ "Shei": "vw",
+ "Shen": "vm",
+ "Sheng": "vn",
+ "Shi": "vi",
+ "Shou": "vr",
+ "Shu": "vu",
+ "Shua": "vf",
+ "Shuai": "vv",
+ "Shuan": "vg",
+ "Shuang": "vz",
+ "Shui": "vd",
+ "Shun": "vy",
+ "Shuo": "vo",
+ "Si": "si",
+ "Song": "sl",
+ "Sou": "sr",
+ "Su": "su",
+ "Suan": "sg",
+ "Sui": "sd",
+ "Sun": "sy",
+ "Suo": "so",
+ "Ta": "ta",
+ "Tai": "tk",
+ "Tan": "tj",
+ "Tang": "th",
+ "Tao": "ts",
+ "Te": "te",
+ "Tei": "tw",
+ "Teng": "tn",
+ "Ti": "ti",
+ "Tian": "tf",
+ "Tiao": "tc",
+ "Tie": "tp",
+ "Ting": "tv",
+ "Tong": "tl",
+ "Tou": "tr",
+ "Tu": "tu",
+ "Tuan": "tg",
+ "Tui": "td",
+ "Tun": "ty",
+ "Tuo": "to",
+ "Xi": "xi",
+ "Xia": "xk",
+ "Xian": "xf",
+ "Xiang": "xm",
+ "Xiao": "xc",
+ "Xie": "xp",
+ "Xin": "xd",
+ "Xing": "xv",
+ "Xiong": "xj",
+ "Xiu": "xt",
+ "Xu": "xu",
+ "Xuan": "xg",
+ "Xue": "xb",
+ "Xun": "xy",
+ "Za": "za",
+ "Zai": "zk",
+ "Zan": "zj",
+ "Zang": "zh",
+ "Zao": "zs",
+ "Ze": "ze",
+ "Zei": "zw",
+ "Zen": "zm",
+ "Zeng": "zn",
+ "Zha": "ea",
+ "Zhai": "ek",
+ "Zhan": "ej",
+ "Zhang": "eh",
+ "Zhao": "es",
+ "Zhe": "ee",
+ "Zhen": "em",
+ "Zheng": "en",
+ "Zhi": "ei",
+ "Zhong": "el",
+ "Zhou": "er",
+ "Zhu": "eu",
+ "Zhua": "ef",
+ "Zhuai": "ev",
+ "Zhuan": "eg",
+ "Zhuang": "ez",
+ "Zhui": "ed",
+ "Zhun": "ey",
+ "Zhuo": "eo",
+ "Zi": "zi",
+ "Zong": "zl",
+ "Zou": "zr",
+ "Zu": "zu",
+ "Zuan": "zg",
+ "Zui": "zd",
+ "Zun": "zy",
+ "Zuo": "zo"
+ }
+}
\ No newline at end of file
From 31cd8949fee2d156f16aaf45cb6e50cfac150e7c Mon Sep 17 00:00:00 2001
From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Sat, 14 Jun 2025 14:39:01 +0800
Subject: [PATCH 1545/1697] Compress json
---
Flow.Launcher/Resources/double_pinyin.json | 3747 +-------------------
1 file changed, 1 insertion(+), 3746 deletions(-)
diff --git a/Flow.Launcher/Resources/double_pinyin.json b/Flow.Launcher/Resources/double_pinyin.json
index 6b8ae06c0..83972038f 100644
--- a/Flow.Launcher/Resources/double_pinyin.json
+++ b/Flow.Launcher/Resources/double_pinyin.json
@@ -1,3746 +1 @@
-{
- "XiaoHe": {
- "Lv": "lv",
- "Lve": "lt",
- "Lue": "lt",
- "Nv": "nv",
- "Nve": "nt",
- "Nue": "nt",
- "A": "aa",
- "O": "oo",
- "E": "ee",
- "Ai": "ai",
- "Ei": "ei",
- "Ao": "ao",
- "Ou": "ou",
- "An": "an",
- "En": "en",
- "Ang": "ah",
- "Eng": "eg",
- "Er": "er",
- "Yi": "yi",
- "Ya": "ya",
- "Yo": "yo",
- "Ye": "ye",
- "Yao": "yc",
- "You": "yz",
- "Yan": "yj",
- "Yin": "yb",
- "Yang": "yh",
- "Ying": "yk",
- "Wu": "wu",
- "Wa": "wa",
- "Wo": "wo",
- "Wai": "wd",
- "Wei": "ww",
- "Wan": "wj",
- "Wen": "wf",
- "Wang": "wh",
- "Weng": "wg",
- "Yu": "yu",
- "Yue": "yt",
- "Yuan": "yr",
- "Yun": "yy",
- "Yong": "ys",
- "Ba": "ba",
- "Bai": "bd",
- "Ban": "bj",
- "Bang": "bh",
- "Bao": "bc",
- "Bei": "bw",
- "Ben": "bf",
- "Beng": "bg",
- "Bi": "bi",
- "Bian": "bm",
- "Biang": "bl",
- "Biao": "bn",
- "Bie": "bp",
- "Bin": "bb",
- "Bing": "bk",
- "Bo": "bo",
- "Bu": "bu",
- "Ca": "ca",
- "Cai": "cd",
- "Can": "cj",
- "Cang": "ch",
- "Cao": "cc",
- "Ce": "ce",
- "Cen": "cf",
- "Ceng": "cg",
- "Cha": "ia",
- "Chai": "id",
- "Chan": "ij",
- "Chang": "ih",
- "Chao": "ic",
- "Che": "ie",
- "Chen": "if",
- "Cheng": "ig",
- "Chi": "ii",
- "Chong": "is",
- "Chou": "iz",
- "Chu": "iu",
- "Chua": "ix",
- "Chuai": "ik",
- "Chuan": "ir",
- "Chuang": "il",
- "Chui": "iv",
- "Chun": "iy",
- "Chuo": "io",
- "Ci": "ci",
- "Cong": "cs",
- "Cou": "cz",
- "Cu": "cu",
- "Cuan": "cr",
- "Cui": "cv",
- "Cun": "cy",
- "Cuo": "co",
- "Da": "da",
- "Dai": "dd",
- "Dan": "dj",
- "Dang": "dh",
- "Dao": "dc",
- "De": "de",
- "Dei": "dw",
- "Den": "df",
- "Deng": "dg",
- "Di": "di",
- "Dia": "dx",
- "Dian": "dm",
- "Diao": "dn",
- "Die": "dp",
- "Ding": "dk",
- "Diu": "dq",
- "Dong": "ds",
- "Dou": "dz",
- "Du": "du",
- "Duan": "dr",
- "Dui": "dv",
- "Dun": "dy",
- "Duo": "do",
- "Fa": "fa",
- "Fan": "fj",
- "Fang": "fh",
- "Fei": "fw",
- "Fen": "ff",
- "Feng": "fg",
- "Fiao": "fn",
- "Fo": "fo",
- "Fou": "fz",
- "Fu": "fu",
- "Ga": "ga",
- "Gai": "gd",
- "Gan": "gj",
- "Gang": "gh",
- "Gao": "gc",
- "Ge": "ge",
- "Gei": "gw",
- "Gen": "gf",
- "Geng": "gg",
- "Gong": "gs",
- "Gou": "gz",
- "Gu": "gu",
- "Gua": "gx",
- "Guai": "gk",
- "Guan": "gr",
- "Guang": "gl",
- "Gui": "gv",
- "Gun": "gy",
- "Guo": "go",
- "Ha": "ha",
- "Hai": "hd",
- "Han": "hj",
- "Hang": "hh",
- "Hao": "hc",
- "He": "he",
- "Hei": "hw",
- "Hen": "hf",
- "Heng": "hg",
- "Hong": "hs",
- "Hou": "hz",
- "Hu": "hu",
- "Hua": "hx",
- "Huai": "hk",
- "Huan": "hr",
- "Huang": "hl",
- "Hui": "hv",
- "Hun": "hy",
- "Huo": "ho",
- "Ji": "ji",
- "Jia": "jx",
- "Jian": "jm",
- "Jiang": "jl",
- "Jiao": "jn",
- "Jie": "jp",
- "Jin": "jb",
- "Jing": "jk",
- "Jiong": "js",
- "Jiu": "jq",
- "Ju": "ju",
- "Juan": "jr",
- "Jue": "jt",
- "Jun": "jy",
- "Ka": "ka",
- "Kai": "kd",
- "Kan": "kj",
- "Kang": "kh",
- "Kao": "kc",
- "Ke": "ke",
- "Ken": "kf",
- "Keng": "kg",
- "Kong": "ks",
- "Kou": "kz",
- "Ku": "ku",
- "Kua": "kx",
- "Kuai": "kk",
- "Kuan": "kr",
- "Kuang": "kl",
- "Kui": "kv",
- "Kun": "ky",
- "Kuo": "ko",
- "La": "la",
- "Lai": "ld",
- "Lan": "lj",
- "Lang": "lh",
- "Lao": "lc",
- "Le": "le",
- "Lei": "lw",
- "Leng": "lg",
- "Li": "li",
- "Lia": "lx",
- "Lian": "lm",
- "Liang": "ll",
- "Liao": "ln",
- "Lie": "lp",
- "Lin": "lb",
- "Ling": "lk",
- "Liu": "lq",
- "Lo": "lo",
- "Long": "ls",
- "Lou": "lz",
- "Lu": "lu",
- "Luan": "lr",
- "Lun": "ly",
- "Luo": "lo",
- "Ma": "ma",
- "Mai": "md",
- "Man": "mj",
- "Mang": "mh",
- "Mao": "mc",
- "Me": "me",
- "Mei": "mw",
- "Men": "mf",
- "Meng": "mg",
- "Mi": "mi",
- "Mian": "mm",
- "Miao": "mn",
- "Mie": "mp",
- "Min": "mb",
- "Ming": "mk",
- "Miu": "mq",
- "Mo": "mo",
- "Mou": "mz",
- "Mu": "mu",
- "Na": "na",
- "Nai": "nd",
- "Nan": "nj",
- "Nang": "nh",
- "Nao": "nc",
- "Ne": "ne",
- "Nei": "nw",
- "Nen": "nf",
- "Neng": "ng",
- "Ni": "ni",
- "Nian": "nm",
- "Niang": "nl",
- "Niao": "nn",
- "Nie": "np",
- "Nin": "nb",
- "Ning": "nk",
- "Niu": "nq",
- "Nong": "ns",
- "Nou": "nz",
- "Nu": "nu",
- "Nuan": "nr",
- "Nun": "ny",
- "Nuo": "no",
- "Pa": "pa",
- "Pai": "pd",
- "Pan": "pj",
- "Pang": "ph",
- "Pao": "pc",
- "Pei": "pw",
- "Pen": "pf",
- "Peng": "pg",
- "Pi": "pi",
- "Pian": "pm",
- "Piao": "pn",
- "Pie": "pp",
- "Pin": "pb",
- "Ping": "pk",
- "Po": "po",
- "Pou": "pz",
- "Pu": "pu",
- "Qi": "qi",
- "Qia": "qx",
- "Qian": "qm",
- "Qiang": "ql",
- "Qiao": "qn",
- "Qie": "qp",
- "Qin": "qb",
- "Qing": "qk",
- "Qiong": "qs",
- "Qiu": "qq",
- "Qu": "qu",
- "Quan": "qr",
- "Que": "qt",
- "Qun": "qy",
- "Ran": "rj",
- "Rang": "rh",
- "Rao": "rc",
- "Re": "re",
- "Ren": "rf",
- "Reng": "rg",
- "Ri": "ri",
- "Rong": "rs",
- "Rou": "rz",
- "Ru": "ru",
- "Rua": "rx",
- "Ruan": "rr",
- "Rui": "rv",
- "Run": "ry",
- "Ruo": "ro",
- "Sa": "sa",
- "Sai": "sd",
- "San": "sj",
- "Sang": "sh",
- "Sao": "sc",
- "Se": "se",
- "Sen": "sf",
- "Seng": "sg",
- "Sha": "ua",
- "Shai": "ud",
- "Shan": "uj",
- "Shang": "uh",
- "Shao": "uc",
- "She": "ue",
- "Shei": "uw",
- "Shen": "uf",
- "Sheng": "ug",
- "Shi": "ui",
- "Shou": "uz",
- "Shu": "uu",
- "Shua": "ux",
- "Shuai": "uk",
- "Shuan": "ur",
- "Shuang": "ul",
- "Shui": "uv",
- "Shun": "uy",
- "Shuo": "uo",
- "Si": "si",
- "Song": "ss",
- "Sou": "sz",
- "Su": "su",
- "Suan": "sr",
- "Sui": "sv",
- "Sun": "sy",
- "Suo": "so",
- "Ta": "ta",
- "Tai": "td",
- "Tan": "tj",
- "Tang": "th",
- "Tao": "tc",
- "Te": "te",
- "Tei": "tw",
- "Teng": "tg",
- "Ti": "ti",
- "Tian": "tm",
- "Tiao": "tn",
- "Tie": "tp",
- "Ting": "tk",
- "Tong": "ts",
- "Tou": "tz",
- "Tu": "tu",
- "Tuan": "tr",
- "Tui": "tv",
- "Tun": "ty",
- "Tuo": "to",
- "Xi": "xi",
- "Xia": "xx",
- "Xian": "xm",
- "Xiang": "xl",
- "Xiao": "xn",
- "Xie": "xp",
- "Xin": "xb",
- "Xing": "xk",
- "Xiong": "xs",
- "Xiu": "xq",
- "Xu": "xu",
- "Xuan": "xr",
- "Xue": "xt",
- "Xun": "xy",
- "Za": "za",
- "Zai": "zd",
- "Zan": "zj",
- "Zang": "zh",
- "Zao": "zc",
- "Ze": "ze",
- "Zei": "zw",
- "Zen": "zf",
- "Zeng": "zg",
- "Zha": "va",
- "Zhai": "vd",
- "Zhan": "vj",
- "Zhang": "vh",
- "Zhao": "vc",
- "Zhe": "ve",
- "Zhen": "vf",
- "Zheng": "vg",
- "Zhi": "vi",
- "Zhong": "vs",
- "Zhou": "vz",
- "Zhu": "vu",
- "Zhua": "vx",
- "Zhuai": "vk",
- "Zhuan": "vr",
- "Zhuang": "vl",
- "Zhui": "vv",
- "Zhun": "vy",
- "Zhuo": "vo",
- "Zi": "zi",
- "Zong": "zs",
- "Zou": "zz",
- "Zu": "zu",
- "Zuan": "zr",
- "Zui": "zv",
- "Zun": "zy",
- "Zuo": "zo"
- },
- "ZiRanMa": {
- "Lv": "lv",
- "Lve": "lt",
- "Lue": "lt",
- "Nv": "nv",
- "Nve": "nt",
- "Nue": "nt",
- "A": "aa",
- "O": "oo",
- "E": "ee",
- "Ai": "ai",
- "Ei": "ei",
- "Ao": "ao",
- "Ou": "ou",
- "An": "an",
- "En": "en",
- "Ang": "ah",
- "Eng": "eg",
- "Er": "er",
- "Yi": "yi",
- "Ya": "ya",
- "Yo": "yo",
- "Ye": "ye",
- "Yao": "yk",
- "You": "yb",
- "Yan": "yj",
- "Yin": "yn",
- "Yang": "yh",
- "Ying": "yy",
- "Wu": "wu",
- "Wa": "wa",
- "Wo": "wo",
- "Wai": "wl",
- "Wei": "wz",
- "Wan": "wj",
- "Wen": "wf",
- "Wang": "wh",
- "Weng": "wg",
- "Yu": "yu",
- "Yue": "yt",
- "Yuan": "yr",
- "Yun": "yp",
- "Yong": "ys",
- "Ba": "ba",
- "Bai": "bl",
- "Ban": "bj",
- "Bang": "bh",
- "Bao": "bk",
- "Bei": "bz",
- "Ben": "bf",
- "Beng": "bg",
- "Bi": "bi",
- "Bian": "bm",
- "Biang": "bd",
- "Biao": "bc",
- "Bie": "bx",
- "Bin": "bn",
- "Bing": "by",
- "Bo": "bo",
- "Bu": "bu",
- "Ca": "ca",
- "Cai": "cl",
- "Can": "cj",
- "Cang": "ch",
- "Cao": "ck",
- "Ce": "ce",
- "Cen": "cf",
- "Ceng": "cg",
- "Cha": "ia",
- "Chai": "il",
- "Chan": "ij",
- "Chang": "ih",
- "Chao": "ik",
- "Che": "ie",
- "Chen": "if",
- "Cheng": "ig",
- "Chi": "ii",
- "Chong": "is",
- "Chou": "ib",
- "Chu": "iu",
- "Chua": "iw",
- "Chuai": "iy",
- "Chuan": "ir",
- "Chuang": "id",
- "Chui": "iv",
- "Chun": "ip",
- "Chuo": "io",
- "Ci": "ci",
- "Cong": "cs",
- "Cou": "cb",
- "Cu": "cu",
- "Cuan": "cr",
- "Cui": "cv",
- "Cun": "cp",
- "Cuo": "co",
- "Da": "da",
- "Dai": "dl",
- "Dan": "dj",
- "Dang": "dh",
- "Dao": "dk",
- "De": "de",
- "Dei": "dz",
- "Den": "df",
- "Deng": "dg",
- "Di": "di",
- "Dia": "dw",
- "Dian": "dm",
- "Diao": "dc",
- "Die": "dx",
- "Ding": "dy",
- "Diu": "dq",
- "Dong": "ds",
- "Dou": "db",
- "Du": "du",
- "Duan": "dr",
- "Dui": "dv",
- "Dun": "dp",
- "Duo": "do",
- "Fa": "fa",
- "Fan": "fj",
- "Fang": "fh",
- "Fei": "fz",
- "Fen": "ff",
- "Feng": "fg",
- "Fiao": "fc",
- "Fo": "fo",
- "Fou": "fb",
- "Fu": "fu",
- "Ga": "ga",
- "Gai": "gl",
- "Gan": "gj",
- "Gang": "gh",
- "Gao": "gk",
- "Ge": "ge",
- "Gei": "gz",
- "Gen": "gf",
- "Geng": "gg",
- "Gong": "gs",
- "Gou": "gb",
- "Gu": "gu",
- "Gua": "gw",
- "Guai": "gy",
- "Guan": "gr",
- "Guang": "gd",
- "Gui": "gv",
- "Gun": "gp",
- "Guo": "go",
- "Ha": "ha",
- "Hai": "hl",
- "Han": "hj",
- "Hang": "hh",
- "Hao": "hk",
- "He": "he",
- "Hei": "hz",
- "Hen": "hf",
- "Heng": "hg",
- "Hong": "hs",
- "Hou": "hb",
- "Hu": "hu",
- "Hua": "hw",
- "Huai": "hy",
- "Huan": "hr",
- "Huang": "hd",
- "Hui": "hv",
- "Hun": "hp",
- "Huo": "ho",
- "Ji": "ji",
- "Jia": "jw",
- "Jian": "jm",
- "Jiang": "jd",
- "Jiao": "jc",
- "Jie": "jx",
- "Jin": "jn",
- "Jing": "jy",
- "Jiong": "js",
- "Jiu": "jq",
- "Ju": "ju",
- "Juan": "jr",
- "Jue": "jt",
- "Jun": "jp",
- "Ka": "ka",
- "Kai": "kl",
- "Kan": "kj",
- "Kang": "kh",
- "Kao": "kk",
- "Ke": "ke",
- "Ken": "kf",
- "Keng": "kg",
- "Kong": "ks",
- "Kou": "kb",
- "Ku": "ku",
- "Kua": "kw",
- "Kuai": "ky",
- "Kuan": "kr",
- "Kuang": "kd",
- "Kui": "kv",
- "Kun": "kp",
- "Kuo": "ko",
- "La": "la",
- "Lai": "ll",
- "Lan": "lj",
- "Lang": "lh",
- "Lao": "lk",
- "Le": "le",
- "Lei": "lz",
- "Leng": "lg",
- "Li": "li",
- "Lia": "lw",
- "Lian": "lm",
- "Liang": "ld",
- "Liao": "lc",
- "Lie": "lx",
- "Lin": "ln",
- "Ling": "ly",
- "Liu": "lq",
- "Lo": "lo",
- "Long": "ls",
- "Lou": "lb",
- "Lu": "lu",
- "Luan": "lr",
- "Lun": "lp",
- "Luo": "lo",
- "Ma": "ma",
- "Mai": "ml",
- "Man": "mj",
- "Mang": "mh",
- "Mao": "mk",
- "Me": "me",
- "Mei": "mz",
- "Men": "mf",
- "Meng": "mg",
- "Mi": "mi",
- "Mian": "mm",
- "Miao": "mc",
- "Mie": "mx",
- "Min": "mn",
- "Ming": "my",
- "Miu": "mq",
- "Mo": "mo",
- "Mou": "mb",
- "Mu": "mu",
- "Na": "na",
- "Nai": "nl",
- "Nan": "nj",
- "Nang": "nh",
- "Nao": "nk",
- "Ne": "ne",
- "Nei": "nz",
- "Nen": "nf",
- "Neng": "ng",
- "Ni": "ni",
- "Nian": "nm",
- "Niang": "nd",
- "Niao": "nc",
- "Nie": "nx",
- "Nin": "nn",
- "Ning": "ny",
- "Niu": "nq",
- "Nong": "ns",
- "Nou": "nb",
- "Nu": "nu",
- "Nuan": "nr",
- "Nun": "np",
- "Nuo": "no",
- "Pa": "pa",
- "Pai": "pl",
- "Pan": "pj",
- "Pang": "ph",
- "Pao": "pk",
- "Pei": "pz",
- "Pen": "pf",
- "Peng": "pg",
- "Pi": "pi",
- "Pian": "pm",
- "Piao": "pc",
- "Pie": "px",
- "Pin": "pn",
- "Ping": "py",
- "Po": "po",
- "Pou": "pb",
- "Pu": "pu",
- "Qi": "qi",
- "Qia": "qw",
- "Qian": "qm",
- "Qiang": "qd",
- "Qiao": "qc",
- "Qie": "qx",
- "Qin": "qn",
- "Qing": "qy",
- "Qiong": "qs",
- "Qiu": "qq",
- "Qu": "qu",
- "Quan": "qr",
- "Que": "qt",
- "Qun": "qp",
- "Ran": "rj",
- "Rang": "rh",
- "Rao": "rk",
- "Re": "re",
- "Ren": "rf",
- "Reng": "rg",
- "Ri": "ri",
- "Rong": "rs",
- "Rou": "rb",
- "Ru": "ru",
- "Rua": "rw",
- "Ruan": "rr",
- "Rui": "rv",
- "Run": "rp",
- "Ruo": "ro",
- "Sa": "sa",
- "Sai": "sl",
- "San": "sj",
- "Sang": "sh",
- "Sao": "sk",
- "Se": "se",
- "Sen": "sf",
- "Seng": "sg",
- "Sha": "ua",
- "Shai": "ul",
- "Shan": "uj",
- "Shang": "uh",
- "Shao": "uk",
- "She": "ue",
- "Shei": "uz",
- "Shen": "uf",
- "Sheng": "ug",
- "Shi": "ui",
- "Shou": "ub",
- "Shu": "uu",
- "Shua": "uw",
- "Shuai": "uy",
- "Shuan": "ur",
- "Shuang": "ud",
- "Shui": "uv",
- "Shun": "up",
- "Shuo": "uo",
- "Si": "si",
- "Song": "ss",
- "Sou": "sb",
- "Su": "su",
- "Suan": "sr",
- "Sui": "sv",
- "Sun": "sp",
- "Suo": "so",
- "Ta": "ta",
- "Tai": "tl",
- "Tan": "tj",
- "Tang": "th",
- "Tao": "tk",
- "Te": "te",
- "Tei": "tz",
- "Teng": "tg",
- "Ti": "ti",
- "Tian": "tm",
- "Tiao": "tc",
- "Tie": "tx",
- "Ting": "ty",
- "Tong": "ts",
- "Tou": "tb",
- "Tu": "tu",
- "Tuan": "tr",
- "Tui": "tv",
- "Tun": "tp",
- "Tuo": "to",
- "Xi": "xi",
- "Xia": "xw",
- "Xian": "xm",
- "Xiang": "xd",
- "Xiao": "xc",
- "Xie": "xx",
- "Xin": "xn",
- "Xing": "xy",
- "Xiong": "xs",
- "Xiu": "xq",
- "Xu": "xu",
- "Xuan": "xr",
- "Xue": "xt",
- "Xun": "xp",
- "Za": "za",
- "Zai": "zl",
- "Zan": "zj",
- "Zang": "zh",
- "Zao": "zk",
- "Ze": "ze",
- "Zei": "zz",
- "Zen": "zf",
- "Zeng": "zg",
- "Zha": "va",
- "Zhai": "vl",
- "Zhan": "vj",
- "Zhang": "vh",
- "Zhao": "vk",
- "Zhe": "ve",
- "Zhen": "vf",
- "Zheng": "vg",
- "Zhi": "vi",
- "Zhong": "vs",
- "Zhou": "vb",
- "Zhu": "vu",
- "Zhua": "vw",
- "Zhuai": "vy",
- "Zhuan": "vr",
- "Zhuang": "vd",
- "Zhui": "vv",
- "Zhun": "vp",
- "Zhuo": "vo",
- "Zi": "zi",
- "Zong": "zs",
- "Zou": "zb",
- "Zu": "zu",
- "Zuan": "zr",
- "Zui": "zv",
- "Zun": "zp",
- "Zuo": "zo"
- },
- "WeiRuan": {
- "Lv": "ly",
- "Lve": "lt",
- "Lue": "lt",
- "Nv": "ny",
- "Nve": "nt",
- "Nue": "nt",
- "A": "oa",
- "O": "oo",
- "E": "oe",
- "Ai": "ol",
- "Ei": "oz",
- "Ao": "ok",
- "Ou": "ob",
- "An": "oj",
- "En": "of",
- "Ang": "oh",
- "Eng": "og",
- "Er": "or",
- "Yi": "yi",
- "Ya": "ya",
- "Yo": "yo",
- "Ye": "ye",
- "Yao": "yk",
- "You": "yb",
- "Yan": "yj",
- "Yin": "yn",
- "Yang": "yh",
- "Ying": "y;",
- "Wu": "wu",
- "Wa": "wa",
- "Wo": "wo",
- "Wai": "wl",
- "Wei": "wz",
- "Wan": "wj",
- "Wen": "wf",
- "Wang": "wh",
- "Weng": "wg",
- "Yu": "yu",
- "Yue": "yt",
- "Yuan": "yr",
- "Yun": "yp",
- "Yong": "ys",
- "Ba": "ba",
- "Bai": "bl",
- "Ban": "bj",
- "Bang": "bh",
- "Bao": "bk",
- "Bei": "bz",
- "Ben": "bf",
- "Beng": "bg",
- "Bi": "bi",
- "Bian": "bm",
- "Biang": "bd",
- "Biao": "bc",
- "Bie": "bx",
- "Bin": "bn",
- "Bing": "b;",
- "Bo": "bo",
- "Bu": "bu",
- "Ca": "ca",
- "Cai": "cl",
- "Can": "cj",
- "Cang": "ch",
- "Cao": "ck",
- "Ce": "ce",
- "Cen": "cf",
- "Ceng": "cg",
- "Cha": "ia",
- "Chai": "il",
- "Chan": "ij",
- "Chang": "ih",
- "Chao": "ik",
- "Che": "ie",
- "Chen": "if",
- "Cheng": "ig",
- "Chi": "ii",
- "Chong": "is",
- "Chou": "ib",
- "Chu": "iu",
- "Chua": "iw",
- "Chuai": "iy",
- "Chuan": "ir",
- "Chuang": "id",
- "Chui": "iv",
- "Chun": "ip",
- "Chuo": "io",
- "Ci": "ci",
- "Cong": "cs",
- "Cou": "cb",
- "Cu": "cu",
- "Cuan": "cr",
- "Cui": "cv",
- "Cun": "cp",
- "Cuo": "co",
- "Da": "da",
- "Dai": "dl",
- "Dan": "dj",
- "Dang": "dh",
- "Dao": "dk",
- "De": "de",
- "Dei": "dz",
- "Den": "df",
- "Deng": "dg",
- "Di": "di",
- "Dia": "dw",
- "Dian": "dm",
- "Diao": "dc",
- "Die": "dx",
- "Ding": "d;",
- "Diu": "dq",
- "Dong": "ds",
- "Dou": "db",
- "Du": "du",
- "Duan": "dr",
- "Dui": "dv",
- "Dun": "dp",
- "Duo": "do",
- "Fa": "fa",
- "Fan": "fj",
- "Fang": "fh",
- "Fei": "fz",
- "Fen": "ff",
- "Feng": "fg",
- "Fiao": "fc",
- "Fo": "fo",
- "Fou": "fb",
- "Fu": "fu",
- "Ga": "ga",
- "Gai": "gl",
- "Gan": "gj",
- "Gang": "gh",
- "Gao": "gk",
- "Ge": "ge",
- "Gei": "gz",
- "Gen": "gf",
- "Geng": "gg",
- "Gong": "gs",
- "Gou": "gb",
- "Gu": "gu",
- "Gua": "gw",
- "Guai": "gy",
- "Guan": "gr",
- "Guang": "gd",
- "Gui": "gv",
- "Gun": "gp",
- "Guo": "go",
- "Ha": "ha",
- "Hai": "hl",
- "Han": "hj",
- "Hang": "hh",
- "Hao": "hk",
- "He": "he",
- "Hei": "hz",
- "Hen": "hf",
- "Heng": "hg",
- "Hong": "hs",
- "Hou": "hb",
- "Hu": "hu",
- "Hua": "hw",
- "Huai": "hy",
- "Huan": "hr",
- "Huang": "hd",
- "Hui": "hv",
- "Hun": "hp",
- "Huo": "ho",
- "Ji": "ji",
- "Jia": "jw",
- "Jian": "jm",
- "Jiang": "jd",
- "Jiao": "jc",
- "Jie": "jx",
- "Jin": "jn",
- "Jing": "j;",
- "Jiong": "js",
- "Jiu": "jq",
- "Ju": "ju",
- "Juan": "jr",
- "Jue": "jt",
- "Jun": "jp",
- "Ka": "ka",
- "Kai": "kl",
- "Kan": "kj",
- "Kang": "kh",
- "Kao": "kk",
- "Ke": "ke",
- "Ken": "kf",
- "Keng": "kg",
- "Kong": "ks",
- "Kou": "kb",
- "Ku": "ku",
- "Kua": "kw",
- "Kuai": "ky",
- "Kuan": "kr",
- "Kuang": "kd",
- "Kui": "kv",
- "Kun": "kp",
- "Kuo": "ko",
- "La": "la",
- "Lai": "ll",
- "Lan": "lj",
- "Lang": "lh",
- "Lao": "lk",
- "Le": "le",
- "Lei": "lz",
- "Leng": "lg",
- "Li": "li",
- "Lia": "lw",
- "Lian": "lm",
- "Liang": "ld",
- "Liao": "lc",
- "Lie": "lx",
- "Lin": "ln",
- "Ling": "l;",
- "Liu": "lq",
- "Lo": "lo",
- "Long": "ls",
- "Lou": "lb",
- "Lu": "lu",
- "Luan": "lr",
- "Lun": "lp",
- "Luo": "lo",
- "Ma": "ma",
- "Mai": "ml",
- "Man": "mj",
- "Mang": "mh",
- "Mao": "mk",
- "Me": "me",
- "Mei": "mz",
- "Men": "mf",
- "Meng": "mg",
- "Mi": "mi",
- "Mian": "mm",
- "Miao": "mc",
- "Mie": "mx",
- "Min": "mn",
- "Ming": "m;",
- "Miu": "mq",
- "Mo": "mo",
- "Mou": "mb",
- "Mu": "mu",
- "Na": "na",
- "Nai": "nl",
- "Nan": "nj",
- "Nang": "nh",
- "Nao": "nk",
- "Ne": "ne",
- "Nei": "nz",
- "Nen": "nf",
- "Neng": "ng",
- "Ni": "ni",
- "Nian": "nm",
- "Niang": "nd",
- "Niao": "nc",
- "Nie": "nx",
- "Nin": "nn",
- "Ning": "n;",
- "Niu": "nq",
- "Nong": "ns",
- "Nou": "nb",
- "Nu": "nu",
- "Nuan": "nr",
- "Nun": "np",
- "Nuo": "no",
- "Pa": "pa",
- "Pai": "pl",
- "Pan": "pj",
- "Pang": "ph",
- "Pao": "pk",
- "Pei": "pz",
- "Pen": "pf",
- "Peng": "pg",
- "Pi": "pi",
- "Pian": "pm",
- "Piao": "pc",
- "Pie": "px",
- "Pin": "pn",
- "Ping": "p;",
- "Po": "po",
- "Pou": "pb",
- "Pu": "pu",
- "Qi": "qi",
- "Qia": "qw",
- "Qian": "qm",
- "Qiang": "qd",
- "Qiao": "qc",
- "Qie": "qx",
- "Qin": "qn",
- "Qing": "q;",
- "Qiong": "qs",
- "Qiu": "qq",
- "Qu": "qu",
- "Quan": "qr",
- "Que": "qt",
- "Qun": "qp",
- "Ran": "rj",
- "Rang": "rh",
- "Rao": "rk",
- "Re": "re",
- "Ren": "rf",
- "Reng": "rg",
- "Ri": "ri",
- "Rong": "rs",
- "Rou": "rb",
- "Ru": "ru",
- "Rua": "rw",
- "Ruan": "rr",
- "Rui": "rv",
- "Run": "rp",
- "Ruo": "ro",
- "Sa": "sa",
- "Sai": "sl",
- "San": "sj",
- "Sang": "sh",
- "Sao": "sk",
- "Se": "se",
- "Sen": "sf",
- "Seng": "sg",
- "Sha": "ua",
- "Shai": "ul",
- "Shan": "uj",
- "Shang": "uh",
- "Shao": "uk",
- "She": "ue",
- "Shei": "uz",
- "Shen": "uf",
- "Sheng": "ug",
- "Shi": "ui",
- "Shou": "ub",
- "Shu": "uu",
- "Shua": "uw",
- "Shuai": "uy",
- "Shuan": "ur",
- "Shuang": "ud",
- "Shui": "uv",
- "Shun": "up",
- "Shuo": "uo",
- "Si": "si",
- "Song": "ss",
- "Sou": "sb",
- "Su": "su",
- "Suan": "sr",
- "Sui": "sv",
- "Sun": "sp",
- "Suo": "so",
- "Ta": "ta",
- "Tai": "tl",
- "Tan": "tj",
- "Tang": "th",
- "Tao": "tk",
- "Te": "te",
- "Tei": "tz",
- "Teng": "tg",
- "Ti": "ti",
- "Tian": "tm",
- "Tiao": "tc",
- "Tie": "tx",
- "Ting": "t;",
- "Tong": "ts",
- "Tou": "tb",
- "Tu": "tu",
- "Tuan": "tr",
- "Tui": "tv",
- "Tun": "tp",
- "Tuo": "to",
- "Xi": "xi",
- "Xia": "xw",
- "Xian": "xm",
- "Xiang": "xd",
- "Xiao": "xc",
- "Xie": "xx",
- "Xin": "xn",
- "Xing": "x;",
- "Xiong": "xs",
- "Xiu": "xq",
- "Xu": "xu",
- "Xuan": "xr",
- "Xue": "xt",
- "Xun": "xp",
- "Za": "za",
- "Zai": "zl",
- "Zan": "zj",
- "Zang": "zh",
- "Zao": "zk",
- "Ze": "ze",
- "Zei": "zz",
- "Zen": "zf",
- "Zeng": "zg",
- "Zha": "va",
- "Zhai": "vl",
- "Zhan": "vj",
- "Zhang": "vh",
- "Zhao": "vk",
- "Zhe": "ve",
- "Zhen": "vf",
- "Zheng": "vg",
- "Zhi": "vi",
- "Zhong": "vs",
- "Zhou": "vb",
- "Zhu": "vu",
- "Zhua": "vw",
- "Zhuai": "vy",
- "Zhuan": "vr",
- "Zhuang": "vd",
- "Zhui": "vv",
- "Zhun": "vp",
- "Zhuo": "vo",
- "Zi": "zi",
- "Zong": "zs",
- "Zou": "zb",
- "Zu": "zu",
- "Zuan": "zr",
- "Zui": "zv",
- "Zun": "zp",
- "Zuo": "zo"
- },
- "ZhiNengABC": {
- "Lv": "lv",
- "Lve": "lm",
- "Lue": "lm",
- "Nv": "nv",
- "Nve": "nm",
- "Nue": "nm",
- "A": "oa",
- "O": "oo",
- "E": "oe",
- "Ai": "ol",
- "Ei": "oq",
- "Ao": "ok",
- "Ou": "ob",
- "An": "oj",
- "En": "of",
- "Ang": "oh",
- "Eng": "og",
- "Er": "or",
- "Yi": "yi",
- "Ya": "ya",
- "Yo": "yo",
- "Ye": "ye",
- "Yao": "yk",
- "You": "yb",
- "Yan": "yj",
- "Yin": "yc",
- "Yang": "yh",
- "Ying": "yy",
- "Wu": "wu",
- "Wa": "wa",
- "Wo": "wo",
- "Wai": "wl",
- "Wei": "wq",
- "Wan": "wj",
- "Wen": "wf",
- "Wang": "wh",
- "Weng": "wg",
- "Yu": "yu",
- "Yue": "ym",
- "Yuan": "yp",
- "Yun": "yn",
- "Yong": "ys",
- "Ba": "ba",
- "Bai": "bl",
- "Ban": "bj",
- "Bang": "bh",
- "Bao": "bk",
- "Bei": "bq",
- "Ben": "bf",
- "Beng": "bg",
- "Bi": "bi",
- "Bian": "bw",
- "Biang": "bt",
- "Biao": "bz",
- "Bie": "bx",
- "Bin": "bc",
- "Bing": "by",
- "Bo": "bo",
- "Bu": "bu",
- "Ca": "ca",
- "Cai": "cl",
- "Can": "cj",
- "Cang": "ch",
- "Cao": "ck",
- "Ce": "ce",
- "Cen": "cf",
- "Ceng": "cg",
- "Cha": "ea",
- "Chai": "el",
- "Chan": "ej",
- "Chang": "eh",
- "Chao": "ek",
- "Che": "ee",
- "Chen": "ef",
- "Cheng": "eg",
- "Chi": "ei",
- "Chong": "es",
- "Chou": "eb",
- "Chu": "eu",
- "Chua": "ed",
- "Chuai": "ec",
- "Chuan": "ep",
- "Chuang": "et",
- "Chui": "em",
- "Chun": "en",
- "Chuo": "eo",
- "Ci": "ci",
- "Cong": "cs",
- "Cou": "cb",
- "Cu": "cu",
- "Cuan": "cp",
- "Cui": "cm",
- "Cun": "cn",
- "Cuo": "co",
- "Da": "da",
- "Dai": "dl",
- "Dan": "dj",
- "Dang": "dh",
- "Dao": "dk",
- "De": "de",
- "Dei": "dq",
- "Den": "df",
- "Deng": "dg",
- "Di": "di",
- "Dia": "dd",
- "Dian": "dw",
- "Diao": "dz",
- "Die": "dx",
- "Ding": "dy",
- "Diu": "dr",
- "Dong": "ds",
- "Dou": "db",
- "Du": "du",
- "Duan": "dp",
- "Dui": "dm",
- "Dun": "dn",
- "Duo": "do",
- "Fa": "fa",
- "Fan": "fj",
- "Fang": "fh",
- "Fei": "fq",
- "Fen": "ff",
- "Feng": "fg",
- "Fiao": "fz",
- "Fo": "fo",
- "Fou": "fb",
- "Fu": "fu",
- "Ga": "ga",
- "Gai": "gl",
- "Gan": "gj",
- "Gang": "gh",
- "Gao": "gk",
- "Ge": "ge",
- "Gei": "gq",
- "Gen": "gf",
- "Geng": "gg",
- "Gong": "gs",
- "Gou": "gb",
- "Gu": "gu",
- "Gua": "gd",
- "Guai": "gc",
- "Guan": "gp",
- "Guang": "gt",
- "Gui": "gm",
- "Gun": "gn",
- "Guo": "go",
- "Ha": "ha",
- "Hai": "hl",
- "Han": "hj",
- "Hang": "hh",
- "Hao": "hk",
- "He": "he",
- "Hei": "hq",
- "Hen": "hf",
- "Heng": "hg",
- "Hong": "hs",
- "Hou": "hb",
- "Hu": "hu",
- "Hua": "hd",
- "Huai": "hc",
- "Huan": "hp",
- "Huang": "ht",
- "Hui": "hm",
- "Hun": "hn",
- "Huo": "ho",
- "Ji": "ji",
- "Jia": "jd",
- "Jian": "jw",
- "Jiang": "jt",
- "Jiao": "jz",
- "Jie": "jx",
- "Jin": "jc",
- "Jing": "jy",
- "Jiong": "js",
- "Jiu": "jr",
- "Ju": "ju",
- "Juan": "jp",
- "Jue": "jm",
- "Jun": "jn",
- "Ka": "ka",
- "Kai": "kl",
- "Kan": "kj",
- "Kang": "kh",
- "Kao": "kk",
- "Ke": "ke",
- "Ken": "kf",
- "Keng": "kg",
- "Kong": "ks",
- "Kou": "kb",
- "Ku": "ku",
- "Kua": "kd",
- "Kuai": "kc",
- "Kuan": "kp",
- "Kuang": "kt",
- "Kui": "km",
- "Kun": "kn",
- "Kuo": "ko",
- "La": "la",
- "Lai": "ll",
- "Lan": "lj",
- "Lang": "lh",
- "Lao": "lk",
- "Le": "le",
- "Lei": "lq",
- "Leng": "lg",
- "Li": "li",
- "Lia": "ld",
- "Lian": "lw",
- "Liang": "lt",
- "Liao": "lz",
- "Lie": "lx",
- "Lin": "lc",
- "Ling": "ly",
- "Liu": "lr",
- "Lo": "lo",
- "Long": "ls",
- "Lou": "lb",
- "Lu": "lu",
- "Luan": "lp",
- "Lun": "ln",
- "Luo": "lo",
- "Ma": "ma",
- "Mai": "ml",
- "Man": "mj",
- "Mang": "mh",
- "Mao": "mk",
- "Me": "me",
- "Mei": "mq",
- "Men": "mf",
- "Meng": "mg",
- "Mi": "mi",
- "Mian": "mw",
- "Miao": "mz",
- "Mie": "mx",
- "Min": "mc",
- "Ming": "my",
- "Miu": "mr",
- "Mo": "mo",
- "Mou": "mb",
- "Mu": "mu",
- "Na": "na",
- "Nai": "nl",
- "Nan": "nj",
- "Nang": "nh",
- "Nao": "nk",
- "Ne": "ne",
- "Nei": "nq",
- "Nen": "nf",
- "Neng": "ng",
- "Ni": "ni",
- "Nian": "nw",
- "Niang": "nt",
- "Niao": "nz",
- "Nie": "nx",
- "Nin": "nc",
- "Ning": "ny",
- "Niu": "nr",
- "Nong": "ns",
- "Nou": "nb",
- "Nu": "nu",
- "Nuan": "np",
- "Nun": "nn",
- "Nuo": "no",
- "Pa": "pa",
- "Pai": "pl",
- "Pan": "pj",
- "Pang": "ph",
- "Pao": "pk",
- "Pei": "pq",
- "Pen": "pf",
- "Peng": "pg",
- "Pi": "pi",
- "Pian": "pw",
- "Piao": "pz",
- "Pie": "px",
- "Pin": "pc",
- "Ping": "py",
- "Po": "po",
- "Pou": "pb",
- "Pu": "pu",
- "Qi": "qi",
- "Qia": "qd",
- "Qian": "qw",
- "Qiang": "qt",
- "Qiao": "qz",
- "Qie": "qx",
- "Qin": "qc",
- "Qing": "qy",
- "Qiong": "qs",
- "Qiu": "qr",
- "Qu": "qu",
- "Quan": "qp",
- "Que": "qm",
- "Qun": "qn",
- "Ran": "rj",
- "Rang": "rh",
- "Rao": "rk",
- "Re": "re",
- "Ren": "rf",
- "Reng": "rg",
- "Ri": "ri",
- "Rong": "rs",
- "Rou": "rb",
- "Ru": "ru",
- "Rua": "rd",
- "Ruan": "rp",
- "Rui": "rm",
- "Run": "rn",
- "Ruo": "ro",
- "Sa": "sa",
- "Sai": "sl",
- "San": "sj",
- "Sang": "sh",
- "Sao": "sk",
- "Se": "se",
- "Sen": "sf",
- "Seng": "sg",
- "Sha": "va",
- "Shai": "vl",
- "Shan": "vj",
- "Shang": "vh",
- "Shao": "vk",
- "She": "ve",
- "Shei": "vq",
- "Shen": "vf",
- "Sheng": "vg",
- "Shi": "vi",
- "Shou": "vb",
- "Shu": "vu",
- "Shua": "vd",
- "Shuai": "vc",
- "Shuan": "vp",
- "Shuang": "vt",
- "Shui": "vm",
- "Shun": "vn",
- "Shuo": "vo",
- "Si": "si",
- "Song": "ss",
- "Sou": "sb",
- "Su": "su",
- "Suan": "sp",
- "Sui": "sm",
- "Sun": "sn",
- "Suo": "so",
- "Ta": "ta",
- "Tai": "tl",
- "Tan": "tj",
- "Tang": "th",
- "Tao": "tk",
- "Te": "te",
- "Tei": "tq",
- "Teng": "tg",
- "Ti": "ti",
- "Tian": "tw",
- "Tiao": "tz",
- "Tie": "tx",
- "Ting": "ty",
- "Tong": "ts",
- "Tou": "tb",
- "Tu": "tu",
- "Tuan": "tp",
- "Tui": "tm",
- "Tun": "tn",
- "Tuo": "to",
- "Xi": "xi",
- "Xia": "xd",
- "Xian": "xw",
- "Xiang": "xt",
- "Xiao": "xz",
- "Xie": "xx",
- "Xin": "xc",
- "Xing": "xy",
- "Xiong": "xs",
- "Xiu": "xr",
- "Xu": "xu",
- "Xuan": "xp",
- "Xue": "xm",
- "Xun": "xn",
- "Za": "za",
- "Zai": "zl",
- "Zan": "zj",
- "Zang": "zh",
- "Zao": "zk",
- "Ze": "ze",
- "Zei": "zq",
- "Zen": "zf",
- "Zeng": "zg",
- "Zha": "aa",
- "Zhai": "al",
- "Zhan": "aj",
- "Zhang": "ah",
- "Zhao": "ak",
- "Zhe": "ae",
- "Zhen": "af",
- "Zheng": "ag",
- "Zhi": "ai",
- "Zhong": "as",
- "Zhou": "ab",
- "Zhu": "au",
- "Zhua": "ad",
- "Zhuai": "ac",
- "Zhuan": "ap",
- "Zhuang": "at",
- "Zhui": "am",
- "Zhun": "an",
- "Zhuo": "ao",
- "Zi": "zi",
- "Zong": "zs",
- "Zou": "zb",
- "Zu": "zu",
- "Zuan": "zp",
- "Zui": "zm",
- "Zun": "zn",
- "Zuo": "zo"
- },
- "ZiGuangPinYin": {
- "Lv": "lv",
- "Lve": "ln",
- "Lue": "ln",
- "Nv": "nv",
- "Nve": "nn",
- "Nue": "nn",
- "A": "oa",
- "O": "oo",
- "E": "oe",
- "Ai": "op",
- "Ei": "ok",
- "Ao": "oq",
- "Ou": "oz",
- "An": "or",
- "En": "ow",
- "Ang": "os",
- "Eng": "ot",
- "Er": "oj",
- "Yi": "yi",
- "Ya": "ya",
- "Yo": "yo",
- "Ye": "ye",
- "Yao": "yq",
- "You": "yz",
- "Yan": "yr",
- "Yin": "yy",
- "Yang": "ys",
- "Ying": "yc",
- "Wu": "wu",
- "Wa": "wa",
- "Wo": "wo",
- "Wai": "wp",
- "Wei": "wk",
- "Wan": "wr",
- "Wen": "ww",
- "Wang": "ws",
- "Weng": "wt",
- "Yu": "yu",
- "Yue": "yn",
- "Yuan": "yl",
- "Yun": "ym",
- "Yong": "yh",
- "Ba": "ba",
- "Bai": "bp",
- "Ban": "br",
- "Bang": "bs",
- "Bao": "bq",
- "Bei": "bk",
- "Ben": "bw",
- "Beng": "bt",
- "Bi": "bi",
- "Bian": "bf",
- "Biang": "bg",
- "Biao": "bb",
- "Bie": "bd",
- "Bin": "by",
- "Bing": "bc",
- "Bo": "bo",
- "Bu": "bu",
- "Ca": "ca",
- "Cai": "cp",
- "Can": "cr",
- "Cang": "cs",
- "Cao": "cq",
- "Ce": "ce",
- "Cen": "cw",
- "Ceng": "ct",
- "Cha": "aa",
- "Chai": "ap",
- "Chan": "ar",
- "Chang": "as",
- "Chao": "aq",
- "Che": "ae",
- "Chen": "aw",
- "Cheng": "at",
- "Chi": "ai",
- "Chong": "ah",
- "Chou": "az",
- "Chu": "au",
- "Chua": "ax",
- "Chuai": "ay",
- "Chuan": "al",
- "Chuang": "ag",
- "Chui": "an",
- "Chun": "am",
- "Chuo": "ao",
- "Ci": "ci",
- "Cong": "ch",
- "Cou": "cz",
- "Cu": "cu",
- "Cuan": "cl",
- "Cui": "cn",
- "Cun": "cm",
- "Cuo": "co",
- "Da": "da",
- "Dai": "dp",
- "Dan": "dr",
- "Dang": "ds",
- "Dao": "dq",
- "De": "de",
- "Dei": "dk",
- "Den": "dw",
- "Deng": "dt",
- "Di": "di",
- "Dia": "dx",
- "Dian": "df",
- "Diao": "db",
- "Die": "dd",
- "Ding": "dc",
- "Diu": "dj",
- "Dong": "dh",
- "Dou": "dz",
- "Du": "du",
- "Duan": "dl",
- "Dui": "dn",
- "Dun": "dm",
- "Duo": "do",
- "Fa": "fa",
- "Fan": "fr",
- "Fang": "fs",
- "Fei": "fk",
- "Fen": "fw",
- "Feng": "ft",
- "Fiao": "fb",
- "Fo": "fo",
- "Fou": "fz",
- "Fu": "fu",
- "Ga": "ga",
- "Gai": "gp",
- "Gan": "gr",
- "Gang": "gs",
- "Gao": "gq",
- "Ge": "ge",
- "Gei": "gk",
- "Gen": "gw",
- "Geng": "gt",
- "Gong": "gh",
- "Gou": "gz",
- "Gu": "gu",
- "Gua": "gx",
- "Guai": "gy",
- "Guan": "gl",
- "Guang": "gg",
- "Gui": "gn",
- "Gun": "gm",
- "Guo": "go",
- "Ha": "ha",
- "Hai": "hp",
- "Han": "hr",
- "Hang": "hs",
- "Hao": "hq",
- "He": "he",
- "Hei": "hk",
- "Hen": "hw",
- "Heng": "ht",
- "Hong": "hh",
- "Hou": "hz",
- "Hu": "hu",
- "Hua": "hx",
- "Huai": "hy",
- "Huan": "hl",
- "Huang": "hg",
- "Hui": "hn",
- "Hun": "hm",
- "Huo": "ho",
- "Ji": "ji",
- "Jia": "jx",
- "Jian": "jf",
- "Jiang": "jg",
- "Jiao": "jb",
- "Jie": "jd",
- "Jin": "jy",
- "Jing": "jc",
- "Jiong": "jh",
- "Jiu": "jj",
- "Ju": "ju",
- "Juan": "jl",
- "Jue": "jn",
- "Jun": "jm",
- "Ka": "ka",
- "Kai": "kp",
- "Kan": "kr",
- "Kang": "ks",
- "Kao": "kq",
- "Ke": "ke",
- "Ken": "kw",
- "Keng": "kt",
- "Kong": "kh",
- "Kou": "kz",
- "Ku": "ku",
- "Kua": "kx",
- "Kuai": "ky",
- "Kuan": "kl",
- "Kuang": "kg",
- "Kui": "kn",
- "Kun": "km",
- "Kuo": "ko",
- "La": "la",
- "Lai": "lp",
- "Lan": "lr",
- "Lang": "ls",
- "Lao": "lq",
- "Le": "le",
- "Lei": "lk",
- "Leng": "lt",
- "Li": "li",
- "Lia": "lx",
- "Lian": "lf",
- "Liang": "lg",
- "Liao": "lb",
- "Lie": "ld",
- "Lin": "ly",
- "Ling": "lc",
- "Liu": "lj",
- "Lo": "lo",
- "Long": "lh",
- "Lou": "lz",
- "Lu": "lu",
- "Luan": "ll",
- "Lun": "lm",
- "Luo": "lo",
- "Ma": "ma",
- "Mai": "mp",
- "Man": "mr",
- "Mang": "ms",
- "Mao": "mq",
- "Me": "me",
- "Mei": "mk",
- "Men": "mw",
- "Meng": "mt",
- "Mi": "mi",
- "Mian": "mf",
- "Miao": "mb",
- "Mie": "md",
- "Min": "my",
- "Ming": "mc",
- "Miu": "mj",
- "Mo": "mo",
- "Mou": "mz",
- "Mu": "mu",
- "Na": "na",
- "Nai": "np",
- "Nan": "nr",
- "Nang": "ns",
- "Nao": "nq",
- "Ne": "ne",
- "Nei": "nk",
- "Nen": "nw",
- "Neng": "nt",
- "Ni": "ni",
- "Nian": "nf",
- "Niang": "ng",
- "Niao": "nb",
- "Nie": "nd",
- "Nin": "ny",
- "Ning": "nc",
- "Niu": "nj",
- "Nong": "nh",
- "Nou": "nz",
- "Nu": "nu",
- "Nuan": "nl",
- "Nun": "nm",
- "Nuo": "no",
- "Pa": "pa",
- "Pai": "pp",
- "Pan": "pr",
- "Pang": "ps",
- "Pao": "pq",
- "Pei": "pk",
- "Pen": "pw",
- "Peng": "pt",
- "Pi": "pi",
- "Pian": "pf",
- "Piao": "pb",
- "Pie": "pd",
- "Pin": "py",
- "Ping": "pc",
- "Po": "po",
- "Pou": "pz",
- "Pu": "pu",
- "Qi": "qi",
- "Qia": "qx",
- "Qian": "qf",
- "Qiang": "qg",
- "Qiao": "qb",
- "Qie": "qd",
- "Qin": "qy",
- "Qing": "qc",
- "Qiong": "qh",
- "Qiu": "qj",
- "Qu": "qu",
- "Quan": "ql",
- "Que": "qn",
- "Qun": "qm",
- "Ran": "rr",
- "Rang": "rs",
- "Rao": "rq",
- "Re": "re",
- "Ren": "rw",
- "Reng": "rt",
- "Ri": "ri",
- "Rong": "rh",
- "Rou": "rz",
- "Ru": "ru",
- "Rua": "rx",
- "Ruan": "rl",
- "Rui": "rn",
- "Run": "rm",
- "Ruo": "ro",
- "Sa": "sa",
- "Sai": "sp",
- "San": "sr",
- "Sang": "ss",
- "Sao": "sq",
- "Se": "se",
- "Sen": "sw",
- "Seng": "st",
- "Sha": "ia",
- "Shai": "ip",
- "Shan": "ir",
- "Shang": "is",
- "Shao": "iq",
- "She": "ie",
- "Shei": "ik",
- "Shen": "iw",
- "Sheng": "it",
- "Shi": "ii",
- "Shou": "iz",
- "Shu": "iu",
- "Shua": "ix",
- "Shuai": "iy",
- "Shuan": "il",
- "Shuang": "ig",
- "Shui": "in",
- "Shun": "im",
- "Shuo": "io",
- "Si": "si",
- "Song": "sh",
- "Sou": "sz",
- "Su": "su",
- "Suan": "sl",
- "Sui": "sn",
- "Sun": "sm",
- "Suo": "so",
- "Ta": "ta",
- "Tai": "tp",
- "Tan": "tr",
- "Tang": "ts",
- "Tao": "tq",
- "Te": "te",
- "Tei": "tk",
- "Teng": "tt",
- "Ti": "ti",
- "Tian": "tf",
- "Tiao": "tb",
- "Tie": "td",
- "Ting": "tc",
- "Tong": "th",
- "Tou": "tz",
- "Tu": "tu",
- "Tuan": "tl",
- "Tui": "tn",
- "Tun": "tm",
- "Tuo": "to",
- "Xi": "xi",
- "Xia": "xx",
- "Xian": "xf",
- "Xiang": "xg",
- "Xiao": "xb",
- "Xie": "xd",
- "Xin": "xy",
- "Xing": "xc",
- "Xiong": "xh",
- "Xiu": "xj",
- "Xu": "xu",
- "Xuan": "xl",
- "Xue": "xn",
- "Xun": "xm",
- "Za": "za",
- "Zai": "zp",
- "Zan": "zr",
- "Zang": "zs",
- "Zao": "zq",
- "Ze": "ze",
- "Zei": "zk",
- "Zen": "zw",
- "Zeng": "zt",
- "Zha": "ua",
- "Zhai": "up",
- "Zhan": "ur",
- "Zhang": "us",
- "Zhao": "uq",
- "Zhe": "ue",
- "Zhen": "uw",
- "Zheng": "ut",
- "Zhi": "ui",
- "Zhong": "uh",
- "Zhou": "uz",
- "Zhu": "uu",
- "Zhua": "ux",
- "Zhuai": "uy",
- "Zhuan": "ul",
- "Zhuang": "ug",
- "Zhui": "un",
- "Zhun": "um",
- "Zhuo": "uo",
- "Zi": "zi",
- "Zong": "zh",
- "Zou": "zz",
- "Zu": "zu",
- "Zuan": "zl",
- "Zui": "zn",
- "Zun": "zm",
- "Zuo": "zo"
- },
- "PinYinJiaJia": {
- "Lv": "lv",
- "Lve": "lx",
- "Lue": "lx",
- "Nv": "nv",
- "Nve": "nx",
- "Nue": "nx",
- "A": "aa",
- "O": "oo",
- "E": "ee",
- "Ai": "as",
- "Ei": "ew",
- "Ao": "ad",
- "Ou": "op",
- "An": "af",
- "En": "er",
- "Ang": "ag",
- "Eng": "et",
- "Er": "eq",
- "Yi": "yi",
- "Ya": "ya",
- "Yo": "yo",
- "Ye": "ye",
- "Yao": "yd",
- "You": "yp",
- "Yan": "yf",
- "Yin": "yl",
- "Yang": "yg",
- "Ying": "yq",
- "Wu": "wu",
- "Wa": "wa",
- "Wo": "wo",
- "Wai": "ws",
- "Wei": "ww",
- "Wan": "wf",
- "Wen": "wr",
- "Wang": "wg",
- "Weng": "wt",
- "Yu": "yu",
- "Yue": "yx",
- "Yuan": "yc",
- "Yun": "yz",
- "Yong": "yy",
- "Ba": "ba",
- "Bai": "bs",
- "Ban": "bf",
- "Bang": "bg",
- "Bao": "bd",
- "Bei": "bw",
- "Ben": "br",
- "Beng": "bt",
- "Bi": "bi",
- "Bian": "bj",
- "Biang": "bh",
- "Biao": "bk",
- "Bie": "bm",
- "Bin": "bl",
- "Bing": "bq",
- "Bo": "bo",
- "Bu": "bu",
- "Ca": "ca",
- "Cai": "cs",
- "Can": "cf",
- "Cang": "cg",
- "Cao": "cd",
- "Ce": "ce",
- "Cen": "cr",
- "Ceng": "ct",
- "Cha": "ua",
- "Chai": "us",
- "Chan": "uf",
- "Chang": "ug",
- "Chao": "ud",
- "Che": "ue",
- "Chen": "ur",
- "Cheng": "ut",
- "Chi": "ui",
- "Chong": "uy",
- "Chou": "up",
- "Chu": "uu",
- "Chua": "ub",
- "Chuai": "ux",
- "Chuan": "uc",
- "Chuang": "uh",
- "Chui": "uv",
- "Chun": "uz",
- "Chuo": "uo",
- "Ci": "ci",
- "Cong": "cy",
- "Cou": "cp",
- "Cu": "cu",
- "Cuan": "cc",
- "Cui": "cv",
- "Cun": "cz",
- "Cuo": "co",
- "Da": "da",
- "Dai": "ds",
- "Dan": "df",
- "Dang": "dg",
- "Dao": "dd",
- "De": "de",
- "Dei": "dw",
- "Den": "dr",
- "Deng": "dt",
- "Di": "di",
- "Dia": "db",
- "Dian": "dj",
- "Diao": "dk",
- "Die": "dm",
- "Ding": "dq",
- "Diu": "dn",
- "Dong": "dy",
- "Dou": "dp",
- "Du": "du",
- "Duan": "dc",
- "Dui": "dv",
- "Dun": "dz",
- "Duo": "do",
- "Fa": "fa",
- "Fan": "ff",
- "Fang": "fg",
- "Fei": "fw",
- "Fen": "fr",
- "Feng": "ft",
- "Fiao": "fk",
- "Fo": "fo",
- "Fou": "fp",
- "Fu": "fu",
- "Ga": "ga",
- "Gai": "gs",
- "Gan": "gf",
- "Gang": "gg",
- "Gao": "gd",
- "Ge": "ge",
- "Gei": "gw",
- "Gen": "gr",
- "Geng": "gt",
- "Gong": "gy",
- "Gou": "gp",
- "Gu": "gu",
- "Gua": "gb",
- "Guai": "gx",
- "Guan": "gc",
- "Guang": "gh",
- "Gui": "gv",
- "Gun": "gz",
- "Guo": "go",
- "Ha": "ha",
- "Hai": "hs",
- "Han": "hf",
- "Hang": "hg",
- "Hao": "hd",
- "He": "he",
- "Hei": "hw",
- "Hen": "hr",
- "Heng": "ht",
- "Hong": "hy",
- "Hou": "hp",
- "Hu": "hu",
- "Hua": "hb",
- "Huai": "hx",
- "Huan": "hc",
- "Huang": "hh",
- "Hui": "hv",
- "Hun": "hz",
- "Huo": "ho",
- "Ji": "ji",
- "Jia": "jb",
- "Jian": "jj",
- "Jiang": "jh",
- "Jiao": "jk",
- "Jie": "jm",
- "Jin": "jl",
- "Jing": "jq",
- "Jiong": "jy",
- "Jiu": "jn",
- "Ju": "ju",
- "Juan": "jc",
- "Jue": "jx",
- "Jun": "jz",
- "Ka": "ka",
- "Kai": "ks",
- "Kan": "kf",
- "Kang": "kg",
- "Kao": "kd",
- "Ke": "ke",
- "Ken": "kr",
- "Keng": "kt",
- "Kong": "ky",
- "Kou": "kp",
- "Ku": "ku",
- "Kua": "kb",
- "Kuai": "kx",
- "Kuan": "kc",
- "Kuang": "kh",
- "Kui": "kv",
- "Kun": "kz",
- "Kuo": "ko",
- "La": "la",
- "Lai": "ls",
- "Lan": "lf",
- "Lang": "lg",
- "Lao": "ld",
- "Le": "le",
- "Lei": "lw",
- "Leng": "lt",
- "Li": "li",
- "Lia": "lb",
- "Lian": "lj",
- "Liang": "lh",
- "Liao": "lk",
- "Lie": "lm",
- "Lin": "ll",
- "Ling": "lq",
- "Liu": "ln",
- "Lo": "lo",
- "Long": "ly",
- "Lou": "lp",
- "Lu": "lu",
- "Luan": "lc",
- "Lun": "lz",
- "Luo": "lo",
- "Ma": "ma",
- "Mai": "ms",
- "Man": "mf",
- "Mang": "mg",
- "Mao": "md",
- "Me": "me",
- "Mei": "mw",
- "Men": "mr",
- "Meng": "mt",
- "Mi": "mi",
- "Mian": "mj",
- "Miao": "mk",
- "Mie": "mm",
- "Min": "ml",
- "Ming": "mq",
- "Miu": "mn",
- "Mo": "mo",
- "Mou": "mp",
- "Mu": "mu",
- "Na": "na",
- "Nai": "ns",
- "Nan": "nf",
- "Nang": "ng",
- "Nao": "nd",
- "Ne": "ne",
- "Nei": "nw",
- "Nen": "nr",
- "Neng": "nt",
- "Ni": "ni",
- "Nian": "nj",
- "Niang": "nh",
- "Niao": "nk",
- "Nie": "nm",
- "Nin": "nl",
- "Ning": "nq",
- "Niu": "nn",
- "Nong": "ny",
- "Nou": "np",
- "Nu": "nu",
- "Nuan": "nc",
- "Nun": "nz",
- "Nuo": "no",
- "Pa": "pa",
- "Pai": "ps",
- "Pan": "pf",
- "Pang": "pg",
- "Pao": "pd",
- "Pei": "pw",
- "Pen": "pr",
- "Peng": "pt",
- "Pi": "pi",
- "Pian": "pj",
- "Piao": "pk",
- "Pie": "pm",
- "Pin": "pl",
- "Ping": "pq",
- "Po": "po",
- "Pou": "pp",
- "Pu": "pu",
- "Qi": "qi",
- "Qia": "qb",
- "Qian": "qj",
- "Qiang": "qh",
- "Qiao": "qk",
- "Qie": "qm",
- "Qin": "ql",
- "Qing": "qq",
- "Qiong": "qy",
- "Qiu": "qn",
- "Qu": "qu",
- "Quan": "qc",
- "Que": "qx",
- "Qun": "qz",
- "Ran": "rf",
- "Rang": "rg",
- "Rao": "rd",
- "Re": "re",
- "Ren": "rr",
- "Reng": "rt",
- "Ri": "ri",
- "Rong": "ry",
- "Rou": "rp",
- "Ru": "ru",
- "Rua": "rb",
- "Ruan": "rc",
- "Rui": "rv",
- "Run": "rz",
- "Ruo": "ro",
- "Sa": "sa",
- "Sai": "ss",
- "San": "sf",
- "Sang": "sg",
- "Sao": "sd",
- "Se": "se",
- "Sen": "sr",
- "Seng": "st",
- "Sha": "ia",
- "Shai": "is",
- "Shan": "if",
- "Shang": "ig",
- "Shao": "id",
- "She": "ie",
- "Shei": "iw",
- "Shen": "ir",
- "Sheng": "it",
- "Shi": "ii",
- "Shou": "ip",
- "Shu": "iu",
- "Shua": "ib",
- "Shuai": "ix",
- "Shuan": "ic",
- "Shuang": "ih",
- "Shui": "iv",
- "Shun": "iz",
- "Shuo": "io",
- "Si": "si",
- "Song": "sy",
- "Sou": "sp",
- "Su": "su",
- "Suan": "sc",
- "Sui": "sv",
- "Sun": "sz",
- "Suo": "so",
- "Ta": "ta",
- "Tai": "ts",
- "Tan": "tf",
- "Tang": "tg",
- "Tao": "td",
- "Te": "te",
- "Tei": "tw",
- "Teng": "tt",
- "Ti": "ti",
- "Tian": "tj",
- "Tiao": "tk",
- "Tie": "tm",
- "Ting": "tq",
- "Tong": "ty",
- "Tou": "tp",
- "Tu": "tu",
- "Tuan": "tc",
- "Tui": "tv",
- "Tun": "tz",
- "Tuo": "to",
- "Xi": "xi",
- "Xia": "xb",
- "Xian": "xj",
- "Xiang": "xh",
- "Xiao": "xk",
- "Xie": "xm",
- "Xin": "xl",
- "Xing": "xq",
- "Xiong": "xy",
- "Xiu": "xn",
- "Xu": "xu",
- "Xuan": "xc",
- "Xue": "xx",
- "Xun": "xz",
- "Za": "za",
- "Zai": "zs",
- "Zan": "zf",
- "Zang": "zg",
- "Zao": "zd",
- "Ze": "ze",
- "Zei": "zw",
- "Zen": "zr",
- "Zeng": "zt",
- "Zha": "va",
- "Zhai": "vs",
- "Zhan": "vf",
- "Zhang": "vg",
- "Zhao": "vd",
- "Zhe": "ve",
- "Zhen": "vr",
- "Zheng": "vt",
- "Zhi": "vi",
- "Zhong": "vy",
- "Zhou": "vp",
- "Zhu": "vu",
- "Zhua": "vb",
- "Zhuai": "vx",
- "Zhuan": "vc",
- "Zhuang": "vh",
- "Zhui": "vv",
- "Zhun": "vz",
- "Zhuo": "vo",
- "Zi": "zi",
- "Zong": "zy",
- "Zou": "zp",
- "Zu": "zu",
- "Zuan": "zc",
- "Zui": "zv",
- "Zun": "zz",
- "Zuo": "zo"
- },
- "XingKongJianDao": {
- "Lv": "lv",
- "Lve": "ly",
- "Lue": "ly",
- "Nv": "nv",
- "Nve": "ny",
- "Nue": "ny",
- "A": "xa",
- "O": "xo",
- "E": "xe",
- "Ai": "xj",
- "Ei": "xw",
- "Ao": "xs",
- "Ou": "xt",
- "An": "xd",
- "En": "xk",
- "Ang": "xf",
- "Eng": "xh",
- "Er": "xu",
- "Yi": "yi",
- "Ya": "ya",
- "Yo": "yo",
- "Ye": "ye",
- "Yao": "ys",
- "You": "yt",
- "Yan": "yd",
- "Yin": "yb",
- "Yang": "yf",
- "Ying": "yg",
- "Wu": "wj",
- "Wa": "ws",
- "Wo": "wo",
- "Wai": "wh",
- "Wei": "ww",
- "Wan": "wf",
- "Wen": "wn",
- "Wang": "wp",
- "Weng": "wr",
- "Yu": "yv",
- "Yue": "yy",
- "Yuan": "yr",
- "Yun": "yw",
- "Yong": "yl",
- "Ba": "ba",
- "Bai": "bj",
- "Ban": "bd",
- "Bang": "bf",
- "Bao": "bs",
- "Bei": "bw",
- "Ben": "bk",
- "Beng": "bh",
- "Bi": "bi",
- "Bian": "bm",
- "Biang": "bx",
- "Biao": "bp",
- "Bie": "bc",
- "Bin": "bb",
- "Bing": "bg",
- "Bo": "bo",
- "Bu": "bu",
- "Ca": "ca",
- "Cai": "cj",
- "Can": "cd",
- "Cang": "cf",
- "Cao": "cs",
- "Ce": "ce",
- "Cen": "ck",
- "Ceng": "ch",
- "Cha": "ja",
- "Chai": "jj",
- "Chan": "jd",
- "Chang": "jf",
- "Chao": "js",
- "Che": "je",
- "Chen": "jk",
- "Cheng": "jh",
- "Chi": "wi",
- "Chong": "wl",
- "Chou": "jt",
- "Chu": "ju",
- "Chua": "wx",
- "Chuai": "wg",
- "Chuan": "wr",
- "Chuang": "wn",
- "Chui": "wy",
- "Chun": "jz",
- "Chuo": "jo",
- "Ci": "ci",
- "Cong": "cl",
- "Cou": "ct",
- "Cu": "cu",
- "Cuan": "cr",
- "Cui": "cy",
- "Cun": "cz",
- "Cuo": "co",
- "Da": "da",
- "Dai": "dj",
- "Dan": "dd",
- "Dang": "df",
- "Dao": "ds",
- "De": "de",
- "Dei": "dw",
- "Den": "dk",
- "Deng": "dh",
- "Di": "di",
- "Dia": "dx",
- "Dian": "dm",
- "Diao": "dp",
- "Die": "dc",
- "Ding": "dg",
- "Diu": "dq",
- "Dong": "dl",
- "Dou": "dt",
- "Du": "du",
- "Duan": "dr",
- "Dui": "dy",
- "Dun": "dz",
- "Duo": "do",
- "Fa": "fs",
- "Fan": "ff",
- "Fang": "fp",
- "Fei": "fw",
- "Fen": "fn",
- "Feng": "fr",
- "Fiao": "fp",
- "Fo": "fl",
- "Fou": "fd",
- "Fu": "fl",
- "Ga": "ga",
- "Gai": "gj",
- "Gan": "gd",
- "Gang": "gf",
- "Gao": "gs",
- "Ge": "ge",
- "Gei": "gw",
- "Gen": "gk",
- "Geng": "gh",
- "Gong": "gl",
- "Gou": "gt",
- "Gu": "gu",
- "Gua": "gx",
- "Guai": "gg",
- "Guan": "gr",
- "Guang": "gn",
- "Gui": "gy",
- "Gun": "gz",
- "Guo": "go",
- "Ha": "ha",
- "Hai": "hj",
- "Han": "hd",
- "Hang": "hf",
- "Hao": "hs",
- "He": "he",
- "Hei": "hw",
- "Hen": "hk",
- "Heng": "hh",
- "Hong": "hl",
- "Hou": "ht",
- "Hu": "hu",
- "Hua": "hx",
- "Huai": "hg",
- "Huan": "hr",
- "Huang": "hn",
- "Hui": "hy",
- "Hun": "hz",
- "Huo": "ho",
- "Ji": "jk",
- "Jia": "js",
- "Jian": "jm",
- "Jiang": "jn",
- "Jiao": "jp",
- "Jie": "jc",
- "Jin": "jb",
- "Jing": "jg",
- "Jiong": "jy",
- "Jiu": "jq",
- "Ju": "jv",
- "Juan": "jt",
- "Jue": "jh",
- "Jun": "jw",
- "Ka": "ka",
- "Kai": "kj",
- "Kan": "kd",
- "Kang": "kf",
- "Kao": "ks",
- "Ke": "ke",
- "Ken": "kk",
- "Keng": "kh",
- "Kong": "kl",
- "Kou": "kt",
- "Ku": "ku",
- "Kua": "kx",
- "Kuai": "kg",
- "Kuan": "kr",
- "Kuang": "kn",
- "Kui": "ky",
- "Kun": "kz",
- "Kuo": "ko",
- "La": "la",
- "Lai": "lj",
- "Lan": "ld",
- "Lang": "lf",
- "Lao": "ls",
- "Le": "le",
- "Lei": "lw",
- "Leng": "lh",
- "Li": "li",
- "Lia": "lx",
- "Lian": "lm",
- "Liang": "ln",
- "Liao": "lp",
- "Lie": "lc",
- "Lin": "lb",
- "Ling": "lg",
- "Liu": "lq",
- "Lo": "ll",
- "Long": "ll",
- "Lou": "lt",
- "Lu": "lu",
- "Luan": "lr",
- "Lun": "lz",
- "Luo": "lo",
- "Ma": "ma",
- "Mai": "mj",
- "Man": "md",
- "Mang": "mf",
- "Mao": "ms",
- "Me": "me",
- "Mei": "mw",
- "Men": "mk",
- "Meng": "mh",
- "Mi": "mi",
- "Mian": "mm",
- "Miao": "mp",
- "Mie": "mc",
- "Min": "mb",
- "Ming": "mg",
- "Miu": "mq",
- "Mo": "mo",
- "Mou": "mt",
- "Mu": "mu",
- "Na": "na",
- "Nai": "nj",
- "Nan": "nd",
- "Nang": "nf",
- "Nao": "ns",
- "Ne": "ne",
- "Nei": "nw",
- "Nen": "nk",
- "Neng": "nh",
- "Ni": "ni",
- "Nian": "nm",
- "Niang": "nn",
- "Niao": "np",
- "Nie": "nc",
- "Nin": "nb",
- "Ning": "ng",
- "Niu": "nq",
- "Nong": "nl",
- "Nou": "nt",
- "Nu": "nu",
- "Nuan": "nr",
- "Nun": "nz",
- "Nuo": "no",
- "Pa": "pa",
- "Pai": "pj",
- "Pan": "pd",
- "Pang": "pf",
- "Pao": "ps",
- "Pei": "pw",
- "Pen": "pk",
- "Peng": "ph",
- "Pi": "pi",
- "Pian": "pm",
- "Piao": "pp",
- "Pie": "pc",
- "Pin": "pb",
- "Ping": "pg",
- "Po": "po",
- "Pou": "pt",
- "Pu": "pu",
- "Qi": "qk",
- "Qia": "qs",
- "Qian": "qm",
- "Qiang": "qx",
- "Qiao": "qp",
- "Qie": "qc",
- "Qin": "qb",
- "Qing": "qg",
- "Qiong": "qy",
- "Qiu": "qq",
- "Qu": "qv",
- "Quan": "qt",
- "Que": "qh",
- "Qun": "qw",
- "Ran": "rd",
- "Rang": "rf",
- "Rao": "rs",
- "Re": "re",
- "Ren": "rk",
- "Reng": "rh",
- "Ri": "ri",
- "Rong": "rl",
- "Rou": "rt",
- "Ru": "ru",
- "Rua": "rx",
- "Ruan": "rr",
- "Rui": "ry",
- "Run": "rz",
- "Ruo": "ro",
- "Sa": "sa",
- "Sai": "sj",
- "San": "sd",
- "Sang": "sf",
- "Sao": "ss",
- "Se": "se",
- "Sen": "sk",
- "Seng": "sh",
- "Sha": "ea",
- "Shai": "ej",
- "Shan": "ed",
- "Shang": "ef",
- "Shao": "es",
- "She": "ee",
- "Shei": "ew",
- "Shen": "ek",
- "Sheng": "eh",
- "Shi": "ei",
- "Shou": "et",
- "Shu": "eu",
- "Shua": "ex",
- "Shuai": "eg",
- "Shuan": "er",
- "Shuang": "en",
- "Shui": "ey",
- "Shun": "ez",
- "Shuo": "eo",
- "Si": "si",
- "Song": "sl",
- "Sou": "st",
- "Su": "su",
- "Suan": "sr",
- "Sui": "sy",
- "Sun": "sz",
- "Suo": "so",
- "Ta": "ta",
- "Tai": "tj",
- "Tan": "td",
- "Tang": "tf",
- "Tao": "ts",
- "Te": "te",
- "Tei": "tw",
- "Teng": "th",
- "Ti": "ti",
- "Tian": "tm",
- "Tiao": "tp",
- "Tie": "tc",
- "Ting": "tg",
- "Tong": "tl",
- "Tou": "tt",
- "Tu": "tu",
- "Tuan": "tr",
- "Tui": "ty",
- "Tun": "tz",
- "Tuo": "to",
- "Xi": "xi",
- "Xia": "xx",
- "Xian": "xm",
- "Xiang": "xn",
- "Xiao": "xp",
- "Xie": "xc",
- "Xin": "xb",
- "Xing": "xg",
- "Xiong": "xl",
- "Xiu": "xq",
- "Xu": "xv",
- "Xuan": "xr",
- "Xue": "xy",
- "Xun": "xw",
- "Za": "za",
- "Zai": "zj",
- "Zan": "zd",
- "Zang": "zf",
- "Zao": "zs",
- "Ze": "ze",
- "Zei": "zw",
- "Zen": "zk",
- "Zeng": "zh",
- "Zha": "qa",
- "Zhai": "fj",
- "Zhan": "qd",
- "Zhang": "qf",
- "Zhao": "fs",
- "Zhe": "fe",
- "Zhen": "qk",
- "Zheng": "qh",
- "Zhi": "fi",
- "Zhong": "fy",
- "Zhou": "qt",
- "Zhu": "qu",
- "Zhua": "fx",
- "Zhuai": "fg",
- "Zhuan": "fr",
- "Zhuang": "fn",
- "Zhui": "fy",
- "Zhun": "fz",
- "Zhuo": "qo",
- "Zi": "zi",
- "Zong": "zl",
- "Zou": "zt",
- "Zu": "zu",
- "Zuan": "zr",
- "Zui": "zy",
- "Zun": "zz",
- "Zuo": "zo"
- },
- "DaNiu": {
- "Lv": "lv",
- "Lve": "lx",
- "Lue": "lx",
- "Nv": "nv",
- "Nve": "nx",
- "Nue": "nx",
- "A": "ea",
- "O": "eo",
- "E": "ee",
- "Ai": "eh",
- "Ei": "ew",
- "Ao": "es",
- "Ou": "er",
- "An": "ed",
- "En": "ek",
- "Ang": "ef",
- "Eng": "ej",
- "Er": "eu",
- "Yi": "yi",
- "Ya": "ya",
- "Yo": "yo",
- "Ye": "ye",
- "Yao": "ys",
- "You": "yr",
- "Yan": "yd",
- "Yin": "yb",
- "Yang": "yf",
- "Ying": "yg",
- "Wu": "wu",
- "Wa": "wa",
- "Wo": "wo",
- "Wai": "wh",
- "Wei": "ww",
- "Wan": "wd",
- "Wen": "wk",
- "Wang": "wf",
- "Weng": "wj",
- "Yu": "yu",
- "Yue": "yh",
- "Yuan": "yj",
- "Yun": "yw",
- "Yong": "yl",
- "Ba": "ba",
- "Bai": "bh",
- "Ban": "bd",
- "Bang": "bf",
- "Bao": "bs",
- "Bei": "bw",
- "Ben": "bk",
- "Beng": "bj",
- "Bi": "bi",
- "Bian": "bc",
- "Biang": "bn",
- "Biao": "bm",
- "Bie": "bp",
- "Bin": "bb",
- "Bing": "bg",
- "Bo": "bo",
- "Bu": "bu",
- "Ca": "ca",
- "Cai": "ch",
- "Can": "cd",
- "Cang": "cf",
- "Cao": "cs",
- "Ce": "ce",
- "Cen": "ck",
- "Ceng": "cj",
- "Cha": "ia",
- "Chai": "ih",
- "Chan": "id",
- "Chang": "if",
- "Chao": "is",
- "Che": "ie",
- "Chen": "ik",
- "Cheng": "ij",
- "Chi": "ii",
- "Chong": "il",
- "Chou": "ir",
- "Chu": "iu",
- "Chua": "iq",
- "Chuai": "ig",
- "Chuan": "iz",
- "Chuang": "ix",
- "Chui": "in",
- "Chun": "iy",
- "Chuo": "io",
- "Ci": "ci",
- "Cong": "cl",
- "Cou": "cr",
- "Cu": "cu",
- "Cuan": "cz",
- "Cui": "cn",
- "Cun": "cy",
- "Cuo": "co",
- "Da": "da",
- "Dai": "dh",
- "Dan": "dd",
- "Dang": "df",
- "Dao": "ds",
- "De": "de",
- "Dei": "dw",
- "Den": "dk",
- "Deng": "dj",
- "Di": "di",
- "Dia": "dk",
- "Dian": "dc",
- "Diao": "dm",
- "Die": "dp",
- "Ding": "dg",
- "Diu": "dt",
- "Dong": "dl",
- "Dou": "dr",
- "Du": "du",
- "Duan": "dz",
- "Dui": "dn",
- "Dun": "dy",
- "Duo": "do",
- "Fa": "fa",
- "Fan": "fd",
- "Fang": "ff",
- "Fei": "fw",
- "Fen": "fk",
- "Feng": "fj",
- "Fiao": "fm",
- "Fo": "fo",
- "Fou": "fr",
- "Fu": "fu",
- "Ga": "ga",
- "Gai": "gh",
- "Gan": "gd",
- "Gang": "gf",
- "Gao": "gs",
- "Ge": "ge",
- "Gei": "gw",
- "Gen": "gk",
- "Geng": "gj",
- "Gong": "gl",
- "Gou": "gr",
- "Gu": "gu",
- "Gua": "gq",
- "Guai": "gg",
- "Guan": "gz",
- "Guang": "gx",
- "Gui": "gn",
- "Gun": "gy",
- "Guo": "go",
- "Ha": "ha",
- "Hai": "hh",
- "Han": "hd",
- "Hang": "hf",
- "Hao": "hs",
- "He": "he",
- "Hei": "hw",
- "Hen": "hk",
- "Heng": "hj",
- "Hong": "hl",
- "Hou": "hr",
- "Hu": "hu",
- "Hua": "hq",
- "Huai": "hg",
- "Huan": "hz",
- "Huang": "hx",
- "Hui": "hn",
- "Hun": "hy",
- "Huo": "ho",
- "Ji": "ji",
- "Jia": "jk",
- "Jian": "jc",
- "Jiang": "jn",
- "Jiao": "jm",
- "Jie": "jp",
- "Jin": "jb",
- "Jing": "jg",
- "Jiong": "jl",
- "Jiu": "jt",
- "Ju": "ju",
- "Juan": "jj",
- "Jue": "jh",
- "Jun": "jw",
- "Ka": "ka",
- "Kai": "kh",
- "Kan": "kd",
- "Kang": "kf",
- "Kao": "ks",
- "Ke": "ke",
- "Ken": "kk",
- "Keng": "kj",
- "Kong": "kl",
- "Kou": "kr",
- "Ku": "ku",
- "Kua": "kq",
- "Kuai": "kg",
- "Kuan": "kz",
- "Kuang": "kx",
- "Kui": "kn",
- "Kun": "ky",
- "Kuo": "ko",
- "La": "la",
- "Lai": "lh",
- "Lan": "ld",
- "Lang": "lf",
- "Lao": "ls",
- "Le": "le",
- "Lei": "lw",
- "Leng": "lj",
- "Li": "li",
- "Lia": "lk",
- "Lian": "lc",
- "Liang": "ln",
- "Liao": "lm",
- "Lie": "lp",
- "Lin": "lb",
- "Ling": "lg",
- "Liu": "lt",
- "Lo": "lo",
- "Long": "ll",
- "Lou": "lr",
- "Lu": "lu",
- "Luan": "lz",
- "Lun": "ly",
- "Luo": "lo",
- "Ma": "ma",
- "Mai": "mh",
- "Man": "md",
- "Mang": "mf",
- "Mao": "ms",
- "Me": "me",
- "Mei": "mw",
- "Men": "mk",
- "Meng": "mj",
- "Mi": "mi",
- "Mian": "mc",
- "Miao": "mm",
- "Mie": "mp",
- "Min": "mb",
- "Ming": "mg",
- "Miu": "mt",
- "Mo": "mo",
- "Mou": "mr",
- "Mu": "mu",
- "Na": "na",
- "Nai": "nh",
- "Nan": "nd",
- "Nang": "nf",
- "Nao": "ns",
- "Ne": "ne",
- "Nei": "nw",
- "Nen": "nk",
- "Neng": "nj",
- "Ni": "ni",
- "Nian": "nc",
- "Niang": "nn",
- "Niao": "nm",
- "Nie": "np",
- "Nin": "nb",
- "Ning": "ng",
- "Niu": "nt",
- "Nong": "nl",
- "Nou": "nr",
- "Nu": "nu",
- "Nuan": "nz",
- "Nun": "ny",
- "Nuo": "no",
- "Pa": "pa",
- "Pai": "ph",
- "Pan": "pd",
- "Pang": "pf",
- "Pao": "ps",
- "Pei": "pw",
- "Pen": "pk",
- "Peng": "pj",
- "Pi": "pi",
- "Pian": "pc",
- "Piao": "pm",
- "Pie": "pp",
- "Pin": "pb",
- "Ping": "pg",
- "Po": "po",
- "Pou": "pr",
- "Pu": "pu",
- "Qi": "qi",
- "Qia": "qk",
- "Qian": "qc",
- "Qiang": "qn",
- "Qiao": "qm",
- "Qie": "qp",
- "Qin": "qb",
- "Qing": "qg",
- "Qiong": "ql",
- "Qiu": "qt",
- "Qu": "qu",
- "Quan": "qj",
- "Que": "qh",
- "Qun": "qw",
- "Ran": "rd",
- "Rang": "rf",
- "Rao": "rs",
- "Re": "re",
- "Ren": "rk",
- "Reng": "rj",
- "Ri": "ri",
- "Rong": "rl",
- "Rou": "rr",
- "Ru": "ru",
- "Rua": "rq",
- "Ruan": "rz",
- "Rui": "rn",
- "Run": "ry",
- "Ruo": "ro",
- "Sa": "sa",
- "Sai": "sh",
- "San": "sd",
- "Sang": "sf",
- "Sao": "ss",
- "Se": "se",
- "Sen": "sk",
- "Seng": "sj",
- "Sha": "ua",
- "Shai": "uh",
- "Shan": "ud",
- "Shang": "uf",
- "Shao": "us",
- "She": "ue",
- "Shei": "uw",
- "Shen": "uk",
- "Sheng": "uj",
- "Shi": "ui",
- "Shou": "ur",
- "Shu": "uu",
- "Shua": "uq",
- "Shuai": "ug",
- "Shuan": "uz",
- "Shuang": "ux",
- "Shui": "un",
- "Shun": "uy",
- "Shuo": "uo",
- "Si": "si",
- "Song": "sl",
- "Sou": "sr",
- "Su": "su",
- "Suan": "sz",
- "Sui": "sn",
- "Sun": "sy",
- "Suo": "so",
- "Ta": "ta",
- "Tai": "th",
- "Tan": "td",
- "Tang": "tf",
- "Tao": "ts",
- "Te": "te",
- "Tei": "tw",
- "Teng": "tj",
- "Ti": "ti",
- "Tian": "tc",
- "Tiao": "tm",
- "Tie": "tp",
- "Ting": "tg",
- "Tong": "tl",
- "Tou": "tr",
- "Tu": "tu",
- "Tuan": "tz",
- "Tui": "tn",
- "Tun": "ty",
- "Tuo": "to",
- "Xi": "xi",
- "Xia": "xk",
- "Xian": "xc",
- "Xiang": "xn",
- "Xiao": "xm",
- "Xie": "xp",
- "Xin": "xb",
- "Xing": "xg",
- "Xiong": "xl",
- "Xiu": "xt",
- "Xu": "xu",
- "Xuan": "xj",
- "Xue": "xh",
- "Xun": "xw",
- "Za": "za",
- "Zai": "zh",
- "Zan": "zd",
- "Zang": "zf",
- "Zao": "zs",
- "Ze": "ze",
- "Zei": "zw",
- "Zen": "zk",
- "Zeng": "zj",
- "Zha": "aa",
- "Zhai": "ah",
- "Zhan": "ad",
- "Zhang": "af",
- "Zhao": "as",
- "Zhe": "ae",
- "Zhen": "ak",
- "Zheng": "aj",
- "Zhi": "ai",
- "Zhong": "al",
- "Zhou": "ar",
- "Zhu": "au",
- "Zhua": "aq",
- "Zhuai": "ag",
- "Zhuan": "az",
- "Zhuang": "ax",
- "Zhui": "an",
- "Zhun": "ay",
- "Zhuo": "ao",
- "Zi": "zi",
- "Zong": "zl",
- "Zou": "zr",
- "Zu": "zu",
- "Zuan": "zz",
- "Zui": "zn",
- "Zun": "zy",
- "Zuo": "zo"
- },
- "XiaoLang": {
- "Lv": "lx",
- "Lve": "lb",
- "Lue": "lb",
- "Nv": "nx",
- "Nve": "nb",
- "Nue": "nb",
- "A": "aa",
- "O": "oo",
- "E": "uu",
- "Ai": "ai",
- "Ei": "ui",
- "Ao": "ao",
- "Ou": "ou",
- "An": "an",
- "En": "un",
- "Ang": "ah",
- "Eng": "un",
- "Er": "ur",
- "Yi": "yi",
- "Ya": "ya",
- "Yo": "yo",
- "Ye": "ye",
- "Yao": "ys",
- "You": "yr",
- "Yan": "yj",
- "Yin": "yd",
- "Yang": "yh",
- "Ying": "yv",
- "Wu": "wu",
- "Wa": "wa",
- "Wo": "wo",
- "Wai": "wk",
- "Wei": "ww",
- "Wan": "wj",
- "Wen": "wm",
- "Wang": "wh",
- "Weng": "wn",
- "Yu": "yu",
- "Yue": "yb",
- "Yuan": "yg",
- "Yun": "yy",
- "Yong": "yl",
- "Ba": "ba",
- "Bai": "bk",
- "Ban": "bj",
- "Bang": "bh",
- "Bao": "bs",
- "Bei": "bw",
- "Ben": "bm",
- "Beng": "bn",
- "Bi": "bi",
- "Bian": "bf",
- "Biang": "bm",
- "Biao": "bc",
- "Bie": "bp",
- "Bin": "bd",
- "Bing": "bv",
- "Bo": "bo",
- "Bu": "bu",
- "Ca": "ca",
- "Cai": "ck",
- "Can": "cj",
- "Cang": "ch",
- "Cao": "cs",
- "Ce": "ce",
- "Cen": "cm",
- "Ceng": "cn",
- "Cha": "ia",
- "Chai": "ik",
- "Chan": "ij",
- "Chang": "ih",
- "Chao": "is",
- "Che": "ie",
- "Chen": "im",
- "Cheng": "in",
- "Chi": "ii",
- "Chong": "il",
- "Chou": "ir",
- "Chu": "iu",
- "Chua": "if",
- "Chuai": "iv",
- "Chuan": "ig",
- "Chuang": "iz",
- "Chui": "id",
- "Chun": "iy",
- "Chuo": "io",
- "Ci": "ci",
- "Cong": "cl",
- "Cou": "cr",
- "Cu": "cu",
- "Cuan": "cg",
- "Cui": "cd",
- "Cun": "cy",
- "Cuo": "co",
- "Da": "da",
- "Dai": "dk",
- "Dan": "dj",
- "Dang": "dh",
- "Dao": "ds",
- "De": "de",
- "Dei": "dw",
- "Den": "dm",
- "Deng": "dn",
- "Di": "di",
- "Dia": "dk",
- "Dian": "df",
- "Diao": "dc",
- "Die": "dp",
- "Ding": "dv",
- "Diu": "dt",
- "Dong": "dl",
- "Dou": "dr",
- "Du": "du",
- "Duan": "dg",
- "Dui": "dd",
- "Dun": "dy",
- "Duo": "do",
- "Fa": "fa",
- "Fan": "fj",
- "Fang": "fh",
- "Fei": "fw",
- "Fen": "fm",
- "Feng": "fn",
- "Fiao": "fc",
- "Fo": "fo",
- "Fou": "fr",
- "Fu": "fu",
- "Ga": "ga",
- "Gai": "gk",
- "Gan": "gj",
- "Gang": "gh",
- "Gao": "gs",
- "Ge": "ge",
- "Gei": "gw",
- "Gen": "gm",
- "Geng": "gn",
- "Gong": "gl",
- "Gou": "gr",
- "Gu": "gu",
- "Gua": "gf",
- "Guai": "gv",
- "Guan": "gg",
- "Guang": "gz",
- "Gui": "gd",
- "Gun": "gy",
- "Guo": "go",
- "Ha": "ha",
- "Hai": "hk",
- "Han": "hj",
- "Hang": "hh",
- "Hao": "hs",
- "He": "he",
- "Hei": "hw",
- "Hen": "hm",
- "Heng": "hn",
- "Hong": "hl",
- "Hou": "hr",
- "Hu": "hu",
- "Hua": "hf",
- "Huai": "hv",
- "Huan": "hg",
- "Huang": "hz",
- "Hui": "hd",
- "Hun": "hy",
- "Huo": "ho",
- "Ji": "ji",
- "Jia": "jk",
- "Jian": "jf",
- "Jiang": "jm",
- "Jiao": "jc",
- "Jie": "jp",
- "Jin": "jd",
- "Jing": "jv",
- "Jiong": "jj",
- "Jiu": "jt",
- "Ju": "ju",
- "Juan": "jg",
- "Jue": "jb",
- "Jun": "jy",
- "Ka": "ka",
- "Kai": "kk",
- "Kan": "kj",
- "Kang": "kh",
- "Kao": "ks",
- "Ke": "ke",
- "Ken": "km",
- "Keng": "kn",
- "Kong": "kl",
- "Kou": "kr",
- "Ku": "ku",
- "Kua": "kf",
- "Kuai": "kv",
- "Kuan": "kg",
- "Kuang": "kz",
- "Kui": "kd",
- "Kun": "ky",
- "Kuo": "ko",
- "La": "la",
- "Lai": "lk",
- "Lan": "lj",
- "Lang": "lh",
- "Lao": "ls",
- "Le": "le",
- "Lei": "lw",
- "Leng": "ln",
- "Li": "li",
- "Lia": "lk",
- "Lian": "lf",
- "Liang": "lm",
- "Liao": "lc",
- "Lie": "lp",
- "Lin": "ld",
- "Ling": "lv",
- "Liu": "lt",
- "Lo": "lo",
- "Long": "ll",
- "Lou": "lr",
- "Lu": "lu",
- "Luan": "lg",
- "Lun": "ly",
- "Luo": "lo",
- "Ma": "ma",
- "Mai": "mk",
- "Man": "mj",
- "Mang": "mh",
- "Mao": "ms",
- "Me": "me",
- "Mei": "mw",
- "Men": "mm",
- "Meng": "mn",
- "Mi": "mi",
- "Mian": "mf",
- "Miao": "mc",
- "Mie": "mp",
- "Min": "md",
- "Ming": "mv",
- "Miu": "mt",
- "Mo": "mo",
- "Mou": "mr",
- "Mu": "mu",
- "Na": "na",
- "Nai": "nk",
- "Nan": "nj",
- "Nang": "nh",
- "Nao": "ns",
- "Ne": "ne",
- "Nei": "nw",
- "Nen": "nm",
- "Neng": "nn",
- "Ni": "ni",
- "Nian": "nf",
- "Niang": "nm",
- "Niao": "nc",
- "Nie": "np",
- "Nin": "nd",
- "Ning": "nv",
- "Niu": "nt",
- "Nong": "nl",
- "Nou": "nr",
- "Nu": "nu",
- "Nuan": "ng",
- "Nun": "ny",
- "Nuo": "no",
- "Pa": "pa",
- "Pai": "pk",
- "Pan": "pj",
- "Pang": "ph",
- "Pao": "ps",
- "Pei": "pw",
- "Pen": "pm",
- "Peng": "pn",
- "Pi": "pi",
- "Pian": "pf",
- "Piao": "pc",
- "Pie": "pp",
- "Pin": "pd",
- "Ping": "pv",
- "Po": "po",
- "Pou": "pr",
- "Pu": "pu",
- "Qi": "qi",
- "Qia": "qk",
- "Qian": "qf",
- "Qiang": "qm",
- "Qiao": "qc",
- "Qie": "qp",
- "Qin": "qd",
- "Qing": "qv",
- "Qiong": "qj",
- "Qiu": "qt",
- "Qu": "qu",
- "Quan": "qg",
- "Que": "qb",
- "Qun": "qy",
- "Ran": "rj",
- "Rang": "rh",
- "Rao": "rs",
- "Re": "re",
- "Ren": "rm",
- "Reng": "rn",
- "Ri": "ri",
- "Rong": "rl",
- "Rou": "rr",
- "Ru": "ru",
- "Rua": "rf",
- "Ruan": "rg",
- "Rui": "rd",
- "Run": "ry",
- "Ruo": "ro",
- "Sa": "sa",
- "Sai": "sk",
- "San": "sj",
- "Sang": "sh",
- "Sao": "ss",
- "Se": "se",
- "Sen": "sm",
- "Seng": "sn",
- "Sha": "va",
- "Shai": "vk",
- "Shan": "vj",
- "Shang": "vh",
- "Shao": "vs",
- "She": "ve",
- "Shei": "vw",
- "Shen": "vm",
- "Sheng": "vn",
- "Shi": "vi",
- "Shou": "vr",
- "Shu": "vu",
- "Shua": "vf",
- "Shuai": "vv",
- "Shuan": "vg",
- "Shuang": "vz",
- "Shui": "vd",
- "Shun": "vy",
- "Shuo": "vo",
- "Si": "si",
- "Song": "sl",
- "Sou": "sr",
- "Su": "su",
- "Suan": "sg",
- "Sui": "sd",
- "Sun": "sy",
- "Suo": "so",
- "Ta": "ta",
- "Tai": "tk",
- "Tan": "tj",
- "Tang": "th",
- "Tao": "ts",
- "Te": "te",
- "Tei": "tw",
- "Teng": "tn",
- "Ti": "ti",
- "Tian": "tf",
- "Tiao": "tc",
- "Tie": "tp",
- "Ting": "tv",
- "Tong": "tl",
- "Tou": "tr",
- "Tu": "tu",
- "Tuan": "tg",
- "Tui": "td",
- "Tun": "ty",
- "Tuo": "to",
- "Xi": "xi",
- "Xia": "xk",
- "Xian": "xf",
- "Xiang": "xm",
- "Xiao": "xc",
- "Xie": "xp",
- "Xin": "xd",
- "Xing": "xv",
- "Xiong": "xj",
- "Xiu": "xt",
- "Xu": "xu",
- "Xuan": "xg",
- "Xue": "xb",
- "Xun": "xy",
- "Za": "za",
- "Zai": "zk",
- "Zan": "zj",
- "Zang": "zh",
- "Zao": "zs",
- "Ze": "ze",
- "Zei": "zw",
- "Zen": "zm",
- "Zeng": "zn",
- "Zha": "ea",
- "Zhai": "ek",
- "Zhan": "ej",
- "Zhang": "eh",
- "Zhao": "es",
- "Zhe": "ee",
- "Zhen": "em",
- "Zheng": "en",
- "Zhi": "ei",
- "Zhong": "el",
- "Zhou": "er",
- "Zhu": "eu",
- "Zhua": "ef",
- "Zhuai": "ev",
- "Zhuan": "eg",
- "Zhuang": "ez",
- "Zhui": "ed",
- "Zhun": "ey",
- "Zhuo": "eo",
- "Zi": "zi",
- "Zong": "zl",
- "Zou": "zr",
- "Zu": "zu",
- "Zuan": "zg",
- "Zui": "zd",
- "Zun": "zy",
- "Zuo": "zo"
- }
-}
\ No newline at end of file
+{"XiaoHe":{"Lv":"lv","Lve":"lt","Lue":"lt","Nv":"nv","Nve":"nt","Nue":"nt","A":"aa","O":"oo","E":"ee","Ai":"ai","Ei":"ei","Ao":"ao","Ou":"ou","An":"an","En":"en","Ang":"ah","Eng":"eg","Er":"er","Yi":"yi","Ya":"ya","Yo":"yo","Ye":"ye","Yao":"yc","You":"yz","Yan":"yj","Yin":"yb","Yang":"yh","Ying":"yk","Wu":"wu","Wa":"wa","Wo":"wo","Wai":"wd","Wei":"ww","Wan":"wj","Wen":"wf","Wang":"wh","Weng":"wg","Yu":"yu","Yue":"yt","Yuan":"yr","Yun":"yy","Yong":"ys","Ba":"ba","Bai":"bd","Ban":"bj","Bang":"bh","Bao":"bc","Bei":"bw","Ben":"bf","Beng":"bg","Bi":"bi","Bian":"bm","Biang":"bl","Biao":"bn","Bie":"bp","Bin":"bb","Bing":"bk","Bo":"bo","Bu":"bu","Ca":"ca","Cai":"cd","Can":"cj","Cang":"ch","Cao":"cc","Ce":"ce","Cen":"cf","Ceng":"cg","Cha":"ia","Chai":"id","Chan":"ij","Chang":"ih","Chao":"ic","Che":"ie","Chen":"if","Cheng":"ig","Chi":"ii","Chong":"is","Chou":"iz","Chu":"iu","Chua":"ix","Chuai":"ik","Chuan":"ir","Chuang":"il","Chui":"iv","Chun":"iy","Chuo":"io","Ci":"ci","Cong":"cs","Cou":"cz","Cu":"cu","Cuan":"cr","Cui":"cv","Cun":"cy","Cuo":"co","Da":"da","Dai":"dd","Dan":"dj","Dang":"dh","Dao":"dc","De":"de","Dei":"dw","Den":"df","Deng":"dg","Di":"di","Dia":"dx","Dian":"dm","Diao":"dn","Die":"dp","Ding":"dk","Diu":"dq","Dong":"ds","Dou":"dz","Du":"du","Duan":"dr","Dui":"dv","Dun":"dy","Duo":"do","Fa":"fa","Fan":"fj","Fang":"fh","Fei":"fw","Fen":"ff","Feng":"fg","Fiao":"fn","Fo":"fo","Fou":"fz","Fu":"fu","Ga":"ga","Gai":"gd","Gan":"gj","Gang":"gh","Gao":"gc","Ge":"ge","Gei":"gw","Gen":"gf","Geng":"gg","Gong":"gs","Gou":"gz","Gu":"gu","Gua":"gx","Guai":"gk","Guan":"gr","Guang":"gl","Gui":"gv","Gun":"gy","Guo":"go","Ha":"ha","Hai":"hd","Han":"hj","Hang":"hh","Hao":"hc","He":"he","Hei":"hw","Hen":"hf","Heng":"hg","Hong":"hs","Hou":"hz","Hu":"hu","Hua":"hx","Huai":"hk","Huan":"hr","Huang":"hl","Hui":"hv","Hun":"hy","Huo":"ho","Ji":"ji","Jia":"jx","Jian":"jm","Jiang":"jl","Jiao":"jn","Jie":"jp","Jin":"jb","Jing":"jk","Jiong":"js","Jiu":"jq","Ju":"ju","Juan":"jr","Jue":"jt","Jun":"jy","Ka":"ka","Kai":"kd","Kan":"kj","Kang":"kh","Kao":"kc","Ke":"ke","Ken":"kf","Keng":"kg","Kong":"ks","Kou":"kz","Ku":"ku","Kua":"kx","Kuai":"kk","Kuan":"kr","Kuang":"kl","Kui":"kv","Kun":"ky","Kuo":"ko","La":"la","Lai":"ld","Lan":"lj","Lang":"lh","Lao":"lc","Le":"le","Lei":"lw","Leng":"lg","Li":"li","Lia":"lx","Lian":"lm","Liang":"ll","Liao":"ln","Lie":"lp","Lin":"lb","Ling":"lk","Liu":"lq","Lo":"lo","Long":"ls","Lou":"lz","Lu":"lu","Luan":"lr","Lun":"ly","Luo":"lo","Ma":"ma","Mai":"md","Man":"mj","Mang":"mh","Mao":"mc","Me":"me","Mei":"mw","Men":"mf","Meng":"mg","Mi":"mi","Mian":"mm","Miao":"mn","Mie":"mp","Min":"mb","Ming":"mk","Miu":"mq","Mo":"mo","Mou":"mz","Mu":"mu","Na":"na","Nai":"nd","Nan":"nj","Nang":"nh","Nao":"nc","Ne":"ne","Nei":"nw","Nen":"nf","Neng":"ng","Ni":"ni","Nian":"nm","Niang":"nl","Niao":"nn","Nie":"np","Nin":"nb","Ning":"nk","Niu":"nq","Nong":"ns","Nou":"nz","Nu":"nu","Nuan":"nr","Nun":"ny","Nuo":"no","Pa":"pa","Pai":"pd","Pan":"pj","Pang":"ph","Pao":"pc","Pei":"pw","Pen":"pf","Peng":"pg","Pi":"pi","Pian":"pm","Piao":"pn","Pie":"pp","Pin":"pb","Ping":"pk","Po":"po","Pou":"pz","Pu":"pu","Qi":"qi","Qia":"qx","Qian":"qm","Qiang":"ql","Qiao":"qn","Qie":"qp","Qin":"qb","Qing":"qk","Qiong":"qs","Qiu":"qq","Qu":"qu","Quan":"qr","Que":"qt","Qun":"qy","Ran":"rj","Rang":"rh","Rao":"rc","Re":"re","Ren":"rf","Reng":"rg","Ri":"ri","Rong":"rs","Rou":"rz","Ru":"ru","Rua":"rx","Ruan":"rr","Rui":"rv","Run":"ry","Ruo":"ro","Sa":"sa","Sai":"sd","San":"sj","Sang":"sh","Sao":"sc","Se":"se","Sen":"sf","Seng":"sg","Sha":"ua","Shai":"ud","Shan":"uj","Shang":"uh","Shao":"uc","She":"ue","Shei":"uw","Shen":"uf","Sheng":"ug","Shi":"ui","Shou":"uz","Shu":"uu","Shua":"ux","Shuai":"uk","Shuan":"ur","Shuang":"ul","Shui":"uv","Shun":"uy","Shuo":"uo","Si":"si","Song":"ss","Sou":"sz","Su":"su","Suan":"sr","Sui":"sv","Sun":"sy","Suo":"so","Ta":"ta","Tai":"td","Tan":"tj","Tang":"th","Tao":"tc","Te":"te","Tei":"tw","Teng":"tg","Ti":"ti","Tian":"tm","Tiao":"tn","Tie":"tp","Ting":"tk","Tong":"ts","Tou":"tz","Tu":"tu","Tuan":"tr","Tui":"tv","Tun":"ty","Tuo":"to","Xi":"xi","Xia":"xx","Xian":"xm","Xiang":"xl","Xiao":"xn","Xie":"xp","Xin":"xb","Xing":"xk","Xiong":"xs","Xiu":"xq","Xu":"xu","Xuan":"xr","Xue":"xt","Xun":"xy","Za":"za","Zai":"zd","Zan":"zj","Zang":"zh","Zao":"zc","Ze":"ze","Zei":"zw","Zen":"zf","Zeng":"zg","Zha":"va","Zhai":"vd","Zhan":"vj","Zhang":"vh","Zhao":"vc","Zhe":"ve","Zhen":"vf","Zheng":"vg","Zhi":"vi","Zhong":"vs","Zhou":"vz","Zhu":"vu","Zhua":"vx","Zhuai":"vk","Zhuan":"vr","Zhuang":"vl","Zhui":"vv","Zhun":"vy","Zhuo":"vo","Zi":"zi","Zong":"zs","Zou":"zz","Zu":"zu","Zuan":"zr","Zui":"zv","Zun":"zy","Zuo":"zo"},"ZiRanMa":{"Lv":"lv","Lve":"lt","Lue":"lt","Nv":"nv","Nve":"nt","Nue":"nt","A":"aa","O":"oo","E":"ee","Ai":"ai","Ei":"ei","Ao":"ao","Ou":"ou","An":"an","En":"en","Ang":"ah","Eng":"eg","Er":"er","Yi":"yi","Ya":"ya","Yo":"yo","Ye":"ye","Yao":"yk","You":"yb","Yan":"yj","Yin":"yn","Yang":"yh","Ying":"yy","Wu":"wu","Wa":"wa","Wo":"wo","Wai":"wl","Wei":"wz","Wan":"wj","Wen":"wf","Wang":"wh","Weng":"wg","Yu":"yu","Yue":"yt","Yuan":"yr","Yun":"yp","Yong":"ys","Ba":"ba","Bai":"bl","Ban":"bj","Bang":"bh","Bao":"bk","Bei":"bz","Ben":"bf","Beng":"bg","Bi":"bi","Bian":"bm","Biang":"bd","Biao":"bc","Bie":"bx","Bin":"bn","Bing":"by","Bo":"bo","Bu":"bu","Ca":"ca","Cai":"cl","Can":"cj","Cang":"ch","Cao":"ck","Ce":"ce","Cen":"cf","Ceng":"cg","Cha":"ia","Chai":"il","Chan":"ij","Chang":"ih","Chao":"ik","Che":"ie","Chen":"if","Cheng":"ig","Chi":"ii","Chong":"is","Chou":"ib","Chu":"iu","Chua":"iw","Chuai":"iy","Chuan":"ir","Chuang":"id","Chui":"iv","Chun":"ip","Chuo":"io","Ci":"ci","Cong":"cs","Cou":"cb","Cu":"cu","Cuan":"cr","Cui":"cv","Cun":"cp","Cuo":"co","Da":"da","Dai":"dl","Dan":"dj","Dang":"dh","Dao":"dk","De":"de","Dei":"dz","Den":"df","Deng":"dg","Di":"di","Dia":"dw","Dian":"dm","Diao":"dc","Die":"dx","Ding":"dy","Diu":"dq","Dong":"ds","Dou":"db","Du":"du","Duan":"dr","Dui":"dv","Dun":"dp","Duo":"do","Fa":"fa","Fan":"fj","Fang":"fh","Fei":"fz","Fen":"ff","Feng":"fg","Fiao":"fc","Fo":"fo","Fou":"fb","Fu":"fu","Ga":"ga","Gai":"gl","Gan":"gj","Gang":"gh","Gao":"gk","Ge":"ge","Gei":"gz","Gen":"gf","Geng":"gg","Gong":"gs","Gou":"gb","Gu":"gu","Gua":"gw","Guai":"gy","Guan":"gr","Guang":"gd","Gui":"gv","Gun":"gp","Guo":"go","Ha":"ha","Hai":"hl","Han":"hj","Hang":"hh","Hao":"hk","He":"he","Hei":"hz","Hen":"hf","Heng":"hg","Hong":"hs","Hou":"hb","Hu":"hu","Hua":"hw","Huai":"hy","Huan":"hr","Huang":"hd","Hui":"hv","Hun":"hp","Huo":"ho","Ji":"ji","Jia":"jw","Jian":"jm","Jiang":"jd","Jiao":"jc","Jie":"jx","Jin":"jn","Jing":"jy","Jiong":"js","Jiu":"jq","Ju":"ju","Juan":"jr","Jue":"jt","Jun":"jp","Ka":"ka","Kai":"kl","Kan":"kj","Kang":"kh","Kao":"kk","Ke":"ke","Ken":"kf","Keng":"kg","Kong":"ks","Kou":"kb","Ku":"ku","Kua":"kw","Kuai":"ky","Kuan":"kr","Kuang":"kd","Kui":"kv","Kun":"kp","Kuo":"ko","La":"la","Lai":"ll","Lan":"lj","Lang":"lh","Lao":"lk","Le":"le","Lei":"lz","Leng":"lg","Li":"li","Lia":"lw","Lian":"lm","Liang":"ld","Liao":"lc","Lie":"lx","Lin":"ln","Ling":"ly","Liu":"lq","Lo":"lo","Long":"ls","Lou":"lb","Lu":"lu","Luan":"lr","Lun":"lp","Luo":"lo","Ma":"ma","Mai":"ml","Man":"mj","Mang":"mh","Mao":"mk","Me":"me","Mei":"mz","Men":"mf","Meng":"mg","Mi":"mi","Mian":"mm","Miao":"mc","Mie":"mx","Min":"mn","Ming":"my","Miu":"mq","Mo":"mo","Mou":"mb","Mu":"mu","Na":"na","Nai":"nl","Nan":"nj","Nang":"nh","Nao":"nk","Ne":"ne","Nei":"nz","Nen":"nf","Neng":"ng","Ni":"ni","Nian":"nm","Niang":"nd","Niao":"nc","Nie":"nx","Nin":"nn","Ning":"ny","Niu":"nq","Nong":"ns","Nou":"nb","Nu":"nu","Nuan":"nr","Nun":"np","Nuo":"no","Pa":"pa","Pai":"pl","Pan":"pj","Pang":"ph","Pao":"pk","Pei":"pz","Pen":"pf","Peng":"pg","Pi":"pi","Pian":"pm","Piao":"pc","Pie":"px","Pin":"pn","Ping":"py","Po":"po","Pou":"pb","Pu":"pu","Qi":"qi","Qia":"qw","Qian":"qm","Qiang":"qd","Qiao":"qc","Qie":"qx","Qin":"qn","Qing":"qy","Qiong":"qs","Qiu":"qq","Qu":"qu","Quan":"qr","Que":"qt","Qun":"qp","Ran":"rj","Rang":"rh","Rao":"rk","Re":"re","Ren":"rf","Reng":"rg","Ri":"ri","Rong":"rs","Rou":"rb","Ru":"ru","Rua":"rw","Ruan":"rr","Rui":"rv","Run":"rp","Ruo":"ro","Sa":"sa","Sai":"sl","San":"sj","Sang":"sh","Sao":"sk","Se":"se","Sen":"sf","Seng":"sg","Sha":"ua","Shai":"ul","Shan":"uj","Shang":"uh","Shao":"uk","She":"ue","Shei":"uz","Shen":"uf","Sheng":"ug","Shi":"ui","Shou":"ub","Shu":"uu","Shua":"uw","Shuai":"uy","Shuan":"ur","Shuang":"ud","Shui":"uv","Shun":"up","Shuo":"uo","Si":"si","Song":"ss","Sou":"sb","Su":"su","Suan":"sr","Sui":"sv","Sun":"sp","Suo":"so","Ta":"ta","Tai":"tl","Tan":"tj","Tang":"th","Tao":"tk","Te":"te","Tei":"tz","Teng":"tg","Ti":"ti","Tian":"tm","Tiao":"tc","Tie":"tx","Ting":"ty","Tong":"ts","Tou":"tb","Tu":"tu","Tuan":"tr","Tui":"tv","Tun":"tp","Tuo":"to","Xi":"xi","Xia":"xw","Xian":"xm","Xiang":"xd","Xiao":"xc","Xie":"xx","Xin":"xn","Xing":"xy","Xiong":"xs","Xiu":"xq","Xu":"xu","Xuan":"xr","Xue":"xt","Xun":"xp","Za":"za","Zai":"zl","Zan":"zj","Zang":"zh","Zao":"zk","Ze":"ze","Zei":"zz","Zen":"zf","Zeng":"zg","Zha":"va","Zhai":"vl","Zhan":"vj","Zhang":"vh","Zhao":"vk","Zhe":"ve","Zhen":"vf","Zheng":"vg","Zhi":"vi","Zhong":"vs","Zhou":"vb","Zhu":"vu","Zhua":"vw","Zhuai":"vy","Zhuan":"vr","Zhuang":"vd","Zhui":"vv","Zhun":"vp","Zhuo":"vo","Zi":"zi","Zong":"zs","Zou":"zb","Zu":"zu","Zuan":"zr","Zui":"zv","Zun":"zp","Zuo":"zo"},"WeiRuan":{"Lv":"ly","Lve":"lt","Lue":"lt","Nv":"ny","Nve":"nt","Nue":"nt","A":"oa","O":"oo","E":"oe","Ai":"ol","Ei":"oz","Ao":"ok","Ou":"ob","An":"oj","En":"of","Ang":"oh","Eng":"og","Er":"or","Yi":"yi","Ya":"ya","Yo":"yo","Ye":"ye","Yao":"yk","You":"yb","Yan":"yj","Yin":"yn","Yang":"yh","Ying":"y;","Wu":"wu","Wa":"wa","Wo":"wo","Wai":"wl","Wei":"wz","Wan":"wj","Wen":"wf","Wang":"wh","Weng":"wg","Yu":"yu","Yue":"yt","Yuan":"yr","Yun":"yp","Yong":"ys","Ba":"ba","Bai":"bl","Ban":"bj","Bang":"bh","Bao":"bk","Bei":"bz","Ben":"bf","Beng":"bg","Bi":"bi","Bian":"bm","Biang":"bd","Biao":"bc","Bie":"bx","Bin":"bn","Bing":"b;","Bo":"bo","Bu":"bu","Ca":"ca","Cai":"cl","Can":"cj","Cang":"ch","Cao":"ck","Ce":"ce","Cen":"cf","Ceng":"cg","Cha":"ia","Chai":"il","Chan":"ij","Chang":"ih","Chao":"ik","Che":"ie","Chen":"if","Cheng":"ig","Chi":"ii","Chong":"is","Chou":"ib","Chu":"iu","Chua":"iw","Chuai":"iy","Chuan":"ir","Chuang":"id","Chui":"iv","Chun":"ip","Chuo":"io","Ci":"ci","Cong":"cs","Cou":"cb","Cu":"cu","Cuan":"cr","Cui":"cv","Cun":"cp","Cuo":"co","Da":"da","Dai":"dl","Dan":"dj","Dang":"dh","Dao":"dk","De":"de","Dei":"dz","Den":"df","Deng":"dg","Di":"di","Dia":"dw","Dian":"dm","Diao":"dc","Die":"dx","Ding":"d;","Diu":"dq","Dong":"ds","Dou":"db","Du":"du","Duan":"dr","Dui":"dv","Dun":"dp","Duo":"do","Fa":"fa","Fan":"fj","Fang":"fh","Fei":"fz","Fen":"ff","Feng":"fg","Fiao":"fc","Fo":"fo","Fou":"fb","Fu":"fu","Ga":"ga","Gai":"gl","Gan":"gj","Gang":"gh","Gao":"gk","Ge":"ge","Gei":"gz","Gen":"gf","Geng":"gg","Gong":"gs","Gou":"gb","Gu":"gu","Gua":"gw","Guai":"gy","Guan":"gr","Guang":"gd","Gui":"gv","Gun":"gp","Guo":"go","Ha":"ha","Hai":"hl","Han":"hj","Hang":"hh","Hao":"hk","He":"he","Hei":"hz","Hen":"hf","Heng":"hg","Hong":"hs","Hou":"hb","Hu":"hu","Hua":"hw","Huai":"hy","Huan":"hr","Huang":"hd","Hui":"hv","Hun":"hp","Huo":"ho","Ji":"ji","Jia":"jw","Jian":"jm","Jiang":"jd","Jiao":"jc","Jie":"jx","Jin":"jn","Jing":"j;","Jiong":"js","Jiu":"jq","Ju":"ju","Juan":"jr","Jue":"jt","Jun":"jp","Ka":"ka","Kai":"kl","Kan":"kj","Kang":"kh","Kao":"kk","Ke":"ke","Ken":"kf","Keng":"kg","Kong":"ks","Kou":"kb","Ku":"ku","Kua":"kw","Kuai":"ky","Kuan":"kr","Kuang":"kd","Kui":"kv","Kun":"kp","Kuo":"ko","La":"la","Lai":"ll","Lan":"lj","Lang":"lh","Lao":"lk","Le":"le","Lei":"lz","Leng":"lg","Li":"li","Lia":"lw","Lian":"lm","Liang":"ld","Liao":"lc","Lie":"lx","Lin":"ln","Ling":"l;","Liu":"lq","Lo":"lo","Long":"ls","Lou":"lb","Lu":"lu","Luan":"lr","Lun":"lp","Luo":"lo","Ma":"ma","Mai":"ml","Man":"mj","Mang":"mh","Mao":"mk","Me":"me","Mei":"mz","Men":"mf","Meng":"mg","Mi":"mi","Mian":"mm","Miao":"mc","Mie":"mx","Min":"mn","Ming":"m;","Miu":"mq","Mo":"mo","Mou":"mb","Mu":"mu","Na":"na","Nai":"nl","Nan":"nj","Nang":"nh","Nao":"nk","Ne":"ne","Nei":"nz","Nen":"nf","Neng":"ng","Ni":"ni","Nian":"nm","Niang":"nd","Niao":"nc","Nie":"nx","Nin":"nn","Ning":"n;","Niu":"nq","Nong":"ns","Nou":"nb","Nu":"nu","Nuan":"nr","Nun":"np","Nuo":"no","Pa":"pa","Pai":"pl","Pan":"pj","Pang":"ph","Pao":"pk","Pei":"pz","Pen":"pf","Peng":"pg","Pi":"pi","Pian":"pm","Piao":"pc","Pie":"px","Pin":"pn","Ping":"p;","Po":"po","Pou":"pb","Pu":"pu","Qi":"qi","Qia":"qw","Qian":"qm","Qiang":"qd","Qiao":"qc","Qie":"qx","Qin":"qn","Qing":"q;","Qiong":"qs","Qiu":"qq","Qu":"qu","Quan":"qr","Que":"qt","Qun":"qp","Ran":"rj","Rang":"rh","Rao":"rk","Re":"re","Ren":"rf","Reng":"rg","Ri":"ri","Rong":"rs","Rou":"rb","Ru":"ru","Rua":"rw","Ruan":"rr","Rui":"rv","Run":"rp","Ruo":"ro","Sa":"sa","Sai":"sl","San":"sj","Sang":"sh","Sao":"sk","Se":"se","Sen":"sf","Seng":"sg","Sha":"ua","Shai":"ul","Shan":"uj","Shang":"uh","Shao":"uk","She":"ue","Shei":"uz","Shen":"uf","Sheng":"ug","Shi":"ui","Shou":"ub","Shu":"uu","Shua":"uw","Shuai":"uy","Shuan":"ur","Shuang":"ud","Shui":"uv","Shun":"up","Shuo":"uo","Si":"si","Song":"ss","Sou":"sb","Su":"su","Suan":"sr","Sui":"sv","Sun":"sp","Suo":"so","Ta":"ta","Tai":"tl","Tan":"tj","Tang":"th","Tao":"tk","Te":"te","Tei":"tz","Teng":"tg","Ti":"ti","Tian":"tm","Tiao":"tc","Tie":"tx","Ting":"t;","Tong":"ts","Tou":"tb","Tu":"tu","Tuan":"tr","Tui":"tv","Tun":"tp","Tuo":"to","Xi":"xi","Xia":"xw","Xian":"xm","Xiang":"xd","Xiao":"xc","Xie":"xx","Xin":"xn","Xing":"x;","Xiong":"xs","Xiu":"xq","Xu":"xu","Xuan":"xr","Xue":"xt","Xun":"xp","Za":"za","Zai":"zl","Zan":"zj","Zang":"zh","Zao":"zk","Ze":"ze","Zei":"zz","Zen":"zf","Zeng":"zg","Zha":"va","Zhai":"vl","Zhan":"vj","Zhang":"vh","Zhao":"vk","Zhe":"ve","Zhen":"vf","Zheng":"vg","Zhi":"vi","Zhong":"vs","Zhou":"vb","Zhu":"vu","Zhua":"vw","Zhuai":"vy","Zhuan":"vr","Zhuang":"vd","Zhui":"vv","Zhun":"vp","Zhuo":"vo","Zi":"zi","Zong":"zs","Zou":"zb","Zu":"zu","Zuan":"zr","Zui":"zv","Zun":"zp","Zuo":"zo"},"ZhiNengABC":{"Lv":"lv","Lve":"lm","Lue":"lm","Nv":"nv","Nve":"nm","Nue":"nm","A":"oa","O":"oo","E":"oe","Ai":"ol","Ei":"oq","Ao":"ok","Ou":"ob","An":"oj","En":"of","Ang":"oh","Eng":"og","Er":"or","Yi":"yi","Ya":"ya","Yo":"yo","Ye":"ye","Yao":"yk","You":"yb","Yan":"yj","Yin":"yc","Yang":"yh","Ying":"yy","Wu":"wu","Wa":"wa","Wo":"wo","Wai":"wl","Wei":"wq","Wan":"wj","Wen":"wf","Wang":"wh","Weng":"wg","Yu":"yu","Yue":"ym","Yuan":"yp","Yun":"yn","Yong":"ys","Ba":"ba","Bai":"bl","Ban":"bj","Bang":"bh","Bao":"bk","Bei":"bq","Ben":"bf","Beng":"bg","Bi":"bi","Bian":"bw","Biang":"bt","Biao":"bz","Bie":"bx","Bin":"bc","Bing":"by","Bo":"bo","Bu":"bu","Ca":"ca","Cai":"cl","Can":"cj","Cang":"ch","Cao":"ck","Ce":"ce","Cen":"cf","Ceng":"cg","Cha":"ea","Chai":"el","Chan":"ej","Chang":"eh","Chao":"ek","Che":"ee","Chen":"ef","Cheng":"eg","Chi":"ei","Chong":"es","Chou":"eb","Chu":"eu","Chua":"ed","Chuai":"ec","Chuan":"ep","Chuang":"et","Chui":"em","Chun":"en","Chuo":"eo","Ci":"ci","Cong":"cs","Cou":"cb","Cu":"cu","Cuan":"cp","Cui":"cm","Cun":"cn","Cuo":"co","Da":"da","Dai":"dl","Dan":"dj","Dang":"dh","Dao":"dk","De":"de","Dei":"dq","Den":"df","Deng":"dg","Di":"di","Dia":"dd","Dian":"dw","Diao":"dz","Die":"dx","Ding":"dy","Diu":"dr","Dong":"ds","Dou":"db","Du":"du","Duan":"dp","Dui":"dm","Dun":"dn","Duo":"do","Fa":"fa","Fan":"fj","Fang":"fh","Fei":"fq","Fen":"ff","Feng":"fg","Fiao":"fz","Fo":"fo","Fou":"fb","Fu":"fu","Ga":"ga","Gai":"gl","Gan":"gj","Gang":"gh","Gao":"gk","Ge":"ge","Gei":"gq","Gen":"gf","Geng":"gg","Gong":"gs","Gou":"gb","Gu":"gu","Gua":"gd","Guai":"gc","Guan":"gp","Guang":"gt","Gui":"gm","Gun":"gn","Guo":"go","Ha":"ha","Hai":"hl","Han":"hj","Hang":"hh","Hao":"hk","He":"he","Hei":"hq","Hen":"hf","Heng":"hg","Hong":"hs","Hou":"hb","Hu":"hu","Hua":"hd","Huai":"hc","Huan":"hp","Huang":"ht","Hui":"hm","Hun":"hn","Huo":"ho","Ji":"ji","Jia":"jd","Jian":"jw","Jiang":"jt","Jiao":"jz","Jie":"jx","Jin":"jc","Jing":"jy","Jiong":"js","Jiu":"jr","Ju":"ju","Juan":"jp","Jue":"jm","Jun":"jn","Ka":"ka","Kai":"kl","Kan":"kj","Kang":"kh","Kao":"kk","Ke":"ke","Ken":"kf","Keng":"kg","Kong":"ks","Kou":"kb","Ku":"ku","Kua":"kd","Kuai":"kc","Kuan":"kp","Kuang":"kt","Kui":"km","Kun":"kn","Kuo":"ko","La":"la","Lai":"ll","Lan":"lj","Lang":"lh","Lao":"lk","Le":"le","Lei":"lq","Leng":"lg","Li":"li","Lia":"ld","Lian":"lw","Liang":"lt","Liao":"lz","Lie":"lx","Lin":"lc","Ling":"ly","Liu":"lr","Lo":"lo","Long":"ls","Lou":"lb","Lu":"lu","Luan":"lp","Lun":"ln","Luo":"lo","Ma":"ma","Mai":"ml","Man":"mj","Mang":"mh","Mao":"mk","Me":"me","Mei":"mq","Men":"mf","Meng":"mg","Mi":"mi","Mian":"mw","Miao":"mz","Mie":"mx","Min":"mc","Ming":"my","Miu":"mr","Mo":"mo","Mou":"mb","Mu":"mu","Na":"na","Nai":"nl","Nan":"nj","Nang":"nh","Nao":"nk","Ne":"ne","Nei":"nq","Nen":"nf","Neng":"ng","Ni":"ni","Nian":"nw","Niang":"nt","Niao":"nz","Nie":"nx","Nin":"nc","Ning":"ny","Niu":"nr","Nong":"ns","Nou":"nb","Nu":"nu","Nuan":"np","Nun":"nn","Nuo":"no","Pa":"pa","Pai":"pl","Pan":"pj","Pang":"ph","Pao":"pk","Pei":"pq","Pen":"pf","Peng":"pg","Pi":"pi","Pian":"pw","Piao":"pz","Pie":"px","Pin":"pc","Ping":"py","Po":"po","Pou":"pb","Pu":"pu","Qi":"qi","Qia":"qd","Qian":"qw","Qiang":"qt","Qiao":"qz","Qie":"qx","Qin":"qc","Qing":"qy","Qiong":"qs","Qiu":"qr","Qu":"qu","Quan":"qp","Que":"qm","Qun":"qn","Ran":"rj","Rang":"rh","Rao":"rk","Re":"re","Ren":"rf","Reng":"rg","Ri":"ri","Rong":"rs","Rou":"rb","Ru":"ru","Rua":"rd","Ruan":"rp","Rui":"rm","Run":"rn","Ruo":"ro","Sa":"sa","Sai":"sl","San":"sj","Sang":"sh","Sao":"sk","Se":"se","Sen":"sf","Seng":"sg","Sha":"va","Shai":"vl","Shan":"vj","Shang":"vh","Shao":"vk","She":"ve","Shei":"vq","Shen":"vf","Sheng":"vg","Shi":"vi","Shou":"vb","Shu":"vu","Shua":"vd","Shuai":"vc","Shuan":"vp","Shuang":"vt","Shui":"vm","Shun":"vn","Shuo":"vo","Si":"si","Song":"ss","Sou":"sb","Su":"su","Suan":"sp","Sui":"sm","Sun":"sn","Suo":"so","Ta":"ta","Tai":"tl","Tan":"tj","Tang":"th","Tao":"tk","Te":"te","Tei":"tq","Teng":"tg","Ti":"ti","Tian":"tw","Tiao":"tz","Tie":"tx","Ting":"ty","Tong":"ts","Tou":"tb","Tu":"tu","Tuan":"tp","Tui":"tm","Tun":"tn","Tuo":"to","Xi":"xi","Xia":"xd","Xian":"xw","Xiang":"xt","Xiao":"xz","Xie":"xx","Xin":"xc","Xing":"xy","Xiong":"xs","Xiu":"xr","Xu":"xu","Xuan":"xp","Xue":"xm","Xun":"xn","Za":"za","Zai":"zl","Zan":"zj","Zang":"zh","Zao":"zk","Ze":"ze","Zei":"zq","Zen":"zf","Zeng":"zg","Zha":"aa","Zhai":"al","Zhan":"aj","Zhang":"ah","Zhao":"ak","Zhe":"ae","Zhen":"af","Zheng":"ag","Zhi":"ai","Zhong":"as","Zhou":"ab","Zhu":"au","Zhua":"ad","Zhuai":"ac","Zhuan":"ap","Zhuang":"at","Zhui":"am","Zhun":"an","Zhuo":"ao","Zi":"zi","Zong":"zs","Zou":"zb","Zu":"zu","Zuan":"zp","Zui":"zm","Zun":"zn","Zuo":"zo"},"ZiGuangPinYin":{"Lv":"lv","Lve":"ln","Lue":"ln","Nv":"nv","Nve":"nn","Nue":"nn","A":"oa","O":"oo","E":"oe","Ai":"op","Ei":"ok","Ao":"oq","Ou":"oz","An":"or","En":"ow","Ang":"os","Eng":"ot","Er":"oj","Yi":"yi","Ya":"ya","Yo":"yo","Ye":"ye","Yao":"yq","You":"yz","Yan":"yr","Yin":"yy","Yang":"ys","Ying":"yc","Wu":"wu","Wa":"wa","Wo":"wo","Wai":"wp","Wei":"wk","Wan":"wr","Wen":"ww","Wang":"ws","Weng":"wt","Yu":"yu","Yue":"yn","Yuan":"yl","Yun":"ym","Yong":"yh","Ba":"ba","Bai":"bp","Ban":"br","Bang":"bs","Bao":"bq","Bei":"bk","Ben":"bw","Beng":"bt","Bi":"bi","Bian":"bf","Biang":"bg","Biao":"bb","Bie":"bd","Bin":"by","Bing":"bc","Bo":"bo","Bu":"bu","Ca":"ca","Cai":"cp","Can":"cr","Cang":"cs","Cao":"cq","Ce":"ce","Cen":"cw","Ceng":"ct","Cha":"aa","Chai":"ap","Chan":"ar","Chang":"as","Chao":"aq","Che":"ae","Chen":"aw","Cheng":"at","Chi":"ai","Chong":"ah","Chou":"az","Chu":"au","Chua":"ax","Chuai":"ay","Chuan":"al","Chuang":"ag","Chui":"an","Chun":"am","Chuo":"ao","Ci":"ci","Cong":"ch","Cou":"cz","Cu":"cu","Cuan":"cl","Cui":"cn","Cun":"cm","Cuo":"co","Da":"da","Dai":"dp","Dan":"dr","Dang":"ds","Dao":"dq","De":"de","Dei":"dk","Den":"dw","Deng":"dt","Di":"di","Dia":"dx","Dian":"df","Diao":"db","Die":"dd","Ding":"dc","Diu":"dj","Dong":"dh","Dou":"dz","Du":"du","Duan":"dl","Dui":"dn","Dun":"dm","Duo":"do","Fa":"fa","Fan":"fr","Fang":"fs","Fei":"fk","Fen":"fw","Feng":"ft","Fiao":"fb","Fo":"fo","Fou":"fz","Fu":"fu","Ga":"ga","Gai":"gp","Gan":"gr","Gang":"gs","Gao":"gq","Ge":"ge","Gei":"gk","Gen":"gw","Geng":"gt","Gong":"gh","Gou":"gz","Gu":"gu","Gua":"gx","Guai":"gy","Guan":"gl","Guang":"gg","Gui":"gn","Gun":"gm","Guo":"go","Ha":"ha","Hai":"hp","Han":"hr","Hang":"hs","Hao":"hq","He":"he","Hei":"hk","Hen":"hw","Heng":"ht","Hong":"hh","Hou":"hz","Hu":"hu","Hua":"hx","Huai":"hy","Huan":"hl","Huang":"hg","Hui":"hn","Hun":"hm","Huo":"ho","Ji":"ji","Jia":"jx","Jian":"jf","Jiang":"jg","Jiao":"jb","Jie":"jd","Jin":"jy","Jing":"jc","Jiong":"jh","Jiu":"jj","Ju":"ju","Juan":"jl","Jue":"jn","Jun":"jm","Ka":"ka","Kai":"kp","Kan":"kr","Kang":"ks","Kao":"kq","Ke":"ke","Ken":"kw","Keng":"kt","Kong":"kh","Kou":"kz","Ku":"ku","Kua":"kx","Kuai":"ky","Kuan":"kl","Kuang":"kg","Kui":"kn","Kun":"km","Kuo":"ko","La":"la","Lai":"lp","Lan":"lr","Lang":"ls","Lao":"lq","Le":"le","Lei":"lk","Leng":"lt","Li":"li","Lia":"lx","Lian":"lf","Liang":"lg","Liao":"lb","Lie":"ld","Lin":"ly","Ling":"lc","Liu":"lj","Lo":"lo","Long":"lh","Lou":"lz","Lu":"lu","Luan":"ll","Lun":"lm","Luo":"lo","Ma":"ma","Mai":"mp","Man":"mr","Mang":"ms","Mao":"mq","Me":"me","Mei":"mk","Men":"mw","Meng":"mt","Mi":"mi","Mian":"mf","Miao":"mb","Mie":"md","Min":"my","Ming":"mc","Miu":"mj","Mo":"mo","Mou":"mz","Mu":"mu","Na":"na","Nai":"np","Nan":"nr","Nang":"ns","Nao":"nq","Ne":"ne","Nei":"nk","Nen":"nw","Neng":"nt","Ni":"ni","Nian":"nf","Niang":"ng","Niao":"nb","Nie":"nd","Nin":"ny","Ning":"nc","Niu":"nj","Nong":"nh","Nou":"nz","Nu":"nu","Nuan":"nl","Nun":"nm","Nuo":"no","Pa":"pa","Pai":"pp","Pan":"pr","Pang":"ps","Pao":"pq","Pei":"pk","Pen":"pw","Peng":"pt","Pi":"pi","Pian":"pf","Piao":"pb","Pie":"pd","Pin":"py","Ping":"pc","Po":"po","Pou":"pz","Pu":"pu","Qi":"qi","Qia":"qx","Qian":"qf","Qiang":"qg","Qiao":"qb","Qie":"qd","Qin":"qy","Qing":"qc","Qiong":"qh","Qiu":"qj","Qu":"qu","Quan":"ql","Que":"qn","Qun":"qm","Ran":"rr","Rang":"rs","Rao":"rq","Re":"re","Ren":"rw","Reng":"rt","Ri":"ri","Rong":"rh","Rou":"rz","Ru":"ru","Rua":"rx","Ruan":"rl","Rui":"rn","Run":"rm","Ruo":"ro","Sa":"sa","Sai":"sp","San":"sr","Sang":"ss","Sao":"sq","Se":"se","Sen":"sw","Seng":"st","Sha":"ia","Shai":"ip","Shan":"ir","Shang":"is","Shao":"iq","She":"ie","Shei":"ik","Shen":"iw","Sheng":"it","Shi":"ii","Shou":"iz","Shu":"iu","Shua":"ix","Shuai":"iy","Shuan":"il","Shuang":"ig","Shui":"in","Shun":"im","Shuo":"io","Si":"si","Song":"sh","Sou":"sz","Su":"su","Suan":"sl","Sui":"sn","Sun":"sm","Suo":"so","Ta":"ta","Tai":"tp","Tan":"tr","Tang":"ts","Tao":"tq","Te":"te","Tei":"tk","Teng":"tt","Ti":"ti","Tian":"tf","Tiao":"tb","Tie":"td","Ting":"tc","Tong":"th","Tou":"tz","Tu":"tu","Tuan":"tl","Tui":"tn","Tun":"tm","Tuo":"to","Xi":"xi","Xia":"xx","Xian":"xf","Xiang":"xg","Xiao":"xb","Xie":"xd","Xin":"xy","Xing":"xc","Xiong":"xh","Xiu":"xj","Xu":"xu","Xuan":"xl","Xue":"xn","Xun":"xm","Za":"za","Zai":"zp","Zan":"zr","Zang":"zs","Zao":"zq","Ze":"ze","Zei":"zk","Zen":"zw","Zeng":"zt","Zha":"ua","Zhai":"up","Zhan":"ur","Zhang":"us","Zhao":"uq","Zhe":"ue","Zhen":"uw","Zheng":"ut","Zhi":"ui","Zhong":"uh","Zhou":"uz","Zhu":"uu","Zhua":"ux","Zhuai":"uy","Zhuan":"ul","Zhuang":"ug","Zhui":"un","Zhun":"um","Zhuo":"uo","Zi":"zi","Zong":"zh","Zou":"zz","Zu":"zu","Zuan":"zl","Zui":"zn","Zun":"zm","Zuo":"zo"},"PinYinJiaJia":{"Lv":"lv","Lve":"lx","Lue":"lx","Nv":"nv","Nve":"nx","Nue":"nx","A":"aa","O":"oo","E":"ee","Ai":"as","Ei":"ew","Ao":"ad","Ou":"op","An":"af","En":"er","Ang":"ag","Eng":"et","Er":"eq","Yi":"yi","Ya":"ya","Yo":"yo","Ye":"ye","Yao":"yd","You":"yp","Yan":"yf","Yin":"yl","Yang":"yg","Ying":"yq","Wu":"wu","Wa":"wa","Wo":"wo","Wai":"ws","Wei":"ww","Wan":"wf","Wen":"wr","Wang":"wg","Weng":"wt","Yu":"yu","Yue":"yx","Yuan":"yc","Yun":"yz","Yong":"yy","Ba":"ba","Bai":"bs","Ban":"bf","Bang":"bg","Bao":"bd","Bei":"bw","Ben":"br","Beng":"bt","Bi":"bi","Bian":"bj","Biang":"bh","Biao":"bk","Bie":"bm","Bin":"bl","Bing":"bq","Bo":"bo","Bu":"bu","Ca":"ca","Cai":"cs","Can":"cf","Cang":"cg","Cao":"cd","Ce":"ce","Cen":"cr","Ceng":"ct","Cha":"ua","Chai":"us","Chan":"uf","Chang":"ug","Chao":"ud","Che":"ue","Chen":"ur","Cheng":"ut","Chi":"ui","Chong":"uy","Chou":"up","Chu":"uu","Chua":"ub","Chuai":"ux","Chuan":"uc","Chuang":"uh","Chui":"uv","Chun":"uz","Chuo":"uo","Ci":"ci","Cong":"cy","Cou":"cp","Cu":"cu","Cuan":"cc","Cui":"cv","Cun":"cz","Cuo":"co","Da":"da","Dai":"ds","Dan":"df","Dang":"dg","Dao":"dd","De":"de","Dei":"dw","Den":"dr","Deng":"dt","Di":"di","Dia":"db","Dian":"dj","Diao":"dk","Die":"dm","Ding":"dq","Diu":"dn","Dong":"dy","Dou":"dp","Du":"du","Duan":"dc","Dui":"dv","Dun":"dz","Duo":"do","Fa":"fa","Fan":"ff","Fang":"fg","Fei":"fw","Fen":"fr","Feng":"ft","Fiao":"fk","Fo":"fo","Fou":"fp","Fu":"fu","Ga":"ga","Gai":"gs","Gan":"gf","Gang":"gg","Gao":"gd","Ge":"ge","Gei":"gw","Gen":"gr","Geng":"gt","Gong":"gy","Gou":"gp","Gu":"gu","Gua":"gb","Guai":"gx","Guan":"gc","Guang":"gh","Gui":"gv","Gun":"gz","Guo":"go","Ha":"ha","Hai":"hs","Han":"hf","Hang":"hg","Hao":"hd","He":"he","Hei":"hw","Hen":"hr","Heng":"ht","Hong":"hy","Hou":"hp","Hu":"hu","Hua":"hb","Huai":"hx","Huan":"hc","Huang":"hh","Hui":"hv","Hun":"hz","Huo":"ho","Ji":"ji","Jia":"jb","Jian":"jj","Jiang":"jh","Jiao":"jk","Jie":"jm","Jin":"jl","Jing":"jq","Jiong":"jy","Jiu":"jn","Ju":"ju","Juan":"jc","Jue":"jx","Jun":"jz","Ka":"ka","Kai":"ks","Kan":"kf","Kang":"kg","Kao":"kd","Ke":"ke","Ken":"kr","Keng":"kt","Kong":"ky","Kou":"kp","Ku":"ku","Kua":"kb","Kuai":"kx","Kuan":"kc","Kuang":"kh","Kui":"kv","Kun":"kz","Kuo":"ko","La":"la","Lai":"ls","Lan":"lf","Lang":"lg","Lao":"ld","Le":"le","Lei":"lw","Leng":"lt","Li":"li","Lia":"lb","Lian":"lj","Liang":"lh","Liao":"lk","Lie":"lm","Lin":"ll","Ling":"lq","Liu":"ln","Lo":"lo","Long":"ly","Lou":"lp","Lu":"lu","Luan":"lc","Lun":"lz","Luo":"lo","Ma":"ma","Mai":"ms","Man":"mf","Mang":"mg","Mao":"md","Me":"me","Mei":"mw","Men":"mr","Meng":"mt","Mi":"mi","Mian":"mj","Miao":"mk","Mie":"mm","Min":"ml","Ming":"mq","Miu":"mn","Mo":"mo","Mou":"mp","Mu":"mu","Na":"na","Nai":"ns","Nan":"nf","Nang":"ng","Nao":"nd","Ne":"ne","Nei":"nw","Nen":"nr","Neng":"nt","Ni":"ni","Nian":"nj","Niang":"nh","Niao":"nk","Nie":"nm","Nin":"nl","Ning":"nq","Niu":"nn","Nong":"ny","Nou":"np","Nu":"nu","Nuan":"nc","Nun":"nz","Nuo":"no","Pa":"pa","Pai":"ps","Pan":"pf","Pang":"pg","Pao":"pd","Pei":"pw","Pen":"pr","Peng":"pt","Pi":"pi","Pian":"pj","Piao":"pk","Pie":"pm","Pin":"pl","Ping":"pq","Po":"po","Pou":"pp","Pu":"pu","Qi":"qi","Qia":"qb","Qian":"qj","Qiang":"qh","Qiao":"qk","Qie":"qm","Qin":"ql","Qing":"qq","Qiong":"qy","Qiu":"qn","Qu":"qu","Quan":"qc","Que":"qx","Qun":"qz","Ran":"rf","Rang":"rg","Rao":"rd","Re":"re","Ren":"rr","Reng":"rt","Ri":"ri","Rong":"ry","Rou":"rp","Ru":"ru","Rua":"rb","Ruan":"rc","Rui":"rv","Run":"rz","Ruo":"ro","Sa":"sa","Sai":"ss","San":"sf","Sang":"sg","Sao":"sd","Se":"se","Sen":"sr","Seng":"st","Sha":"ia","Shai":"is","Shan":"if","Shang":"ig","Shao":"id","She":"ie","Shei":"iw","Shen":"ir","Sheng":"it","Shi":"ii","Shou":"ip","Shu":"iu","Shua":"ib","Shuai":"ix","Shuan":"ic","Shuang":"ih","Shui":"iv","Shun":"iz","Shuo":"io","Si":"si","Song":"sy","Sou":"sp","Su":"su","Suan":"sc","Sui":"sv","Sun":"sz","Suo":"so","Ta":"ta","Tai":"ts","Tan":"tf","Tang":"tg","Tao":"td","Te":"te","Tei":"tw","Teng":"tt","Ti":"ti","Tian":"tj","Tiao":"tk","Tie":"tm","Ting":"tq","Tong":"ty","Tou":"tp","Tu":"tu","Tuan":"tc","Tui":"tv","Tun":"tz","Tuo":"to","Xi":"xi","Xia":"xb","Xian":"xj","Xiang":"xh","Xiao":"xk","Xie":"xm","Xin":"xl","Xing":"xq","Xiong":"xy","Xiu":"xn","Xu":"xu","Xuan":"xc","Xue":"xx","Xun":"xz","Za":"za","Zai":"zs","Zan":"zf","Zang":"zg","Zao":"zd","Ze":"ze","Zei":"zw","Zen":"zr","Zeng":"zt","Zha":"va","Zhai":"vs","Zhan":"vf","Zhang":"vg","Zhao":"vd","Zhe":"ve","Zhen":"vr","Zheng":"vt","Zhi":"vi","Zhong":"vy","Zhou":"vp","Zhu":"vu","Zhua":"vb","Zhuai":"vx","Zhuan":"vc","Zhuang":"vh","Zhui":"vv","Zhun":"vz","Zhuo":"vo","Zi":"zi","Zong":"zy","Zou":"zp","Zu":"zu","Zuan":"zc","Zui":"zv","Zun":"zz","Zuo":"zo"},"XingKongJianDao":{"Lv":"lv","Lve":"ly","Lue":"ly","Nv":"nv","Nve":"ny","Nue":"ny","A":"xa","O":"xo","E":"xe","Ai":"xj","Ei":"xw","Ao":"xs","Ou":"xt","An":"xd","En":"xk","Ang":"xf","Eng":"xh","Er":"xu","Yi":"yi","Ya":"ya","Yo":"yo","Ye":"ye","Yao":"ys","You":"yt","Yan":"yd","Yin":"yb","Yang":"yf","Ying":"yg","Wu":"wj","Wa":"ws","Wo":"wo","Wai":"wh","Wei":"ww","Wan":"wf","Wen":"wn","Wang":"wp","Weng":"wr","Yu":"yv","Yue":"yy","Yuan":"yr","Yun":"yw","Yong":"yl","Ba":"ba","Bai":"bj","Ban":"bd","Bang":"bf","Bao":"bs","Bei":"bw","Ben":"bk","Beng":"bh","Bi":"bi","Bian":"bm","Biang":"bx","Biao":"bp","Bie":"bc","Bin":"bb","Bing":"bg","Bo":"bo","Bu":"bu","Ca":"ca","Cai":"cj","Can":"cd","Cang":"cf","Cao":"cs","Ce":"ce","Cen":"ck","Ceng":"ch","Cha":"ja","Chai":"jj","Chan":"jd","Chang":"jf","Chao":"js","Che":"je","Chen":"jk","Cheng":"jh","Chi":"wi","Chong":"wl","Chou":"jt","Chu":"ju","Chua":"wx","Chuai":"wg","Chuan":"wr","Chuang":"wn","Chui":"wy","Chun":"jz","Chuo":"jo","Ci":"ci","Cong":"cl","Cou":"ct","Cu":"cu","Cuan":"cr","Cui":"cy","Cun":"cz","Cuo":"co","Da":"da","Dai":"dj","Dan":"dd","Dang":"df","Dao":"ds","De":"de","Dei":"dw","Den":"dk","Deng":"dh","Di":"di","Dia":"dx","Dian":"dm","Diao":"dp","Die":"dc","Ding":"dg","Diu":"dq","Dong":"dl","Dou":"dt","Du":"du","Duan":"dr","Dui":"dy","Dun":"dz","Duo":"do","Fa":"fs","Fan":"ff","Fang":"fp","Fei":"fw","Fen":"fn","Feng":"fr","Fiao":"fp","Fo":"fl","Fou":"fd","Fu":"fl","Ga":"ga","Gai":"gj","Gan":"gd","Gang":"gf","Gao":"gs","Ge":"ge","Gei":"gw","Gen":"gk","Geng":"gh","Gong":"gl","Gou":"gt","Gu":"gu","Gua":"gx","Guai":"gg","Guan":"gr","Guang":"gn","Gui":"gy","Gun":"gz","Guo":"go","Ha":"ha","Hai":"hj","Han":"hd","Hang":"hf","Hao":"hs","He":"he","Hei":"hw","Hen":"hk","Heng":"hh","Hong":"hl","Hou":"ht","Hu":"hu","Hua":"hx","Huai":"hg","Huan":"hr","Huang":"hn","Hui":"hy","Hun":"hz","Huo":"ho","Ji":"jk","Jia":"js","Jian":"jm","Jiang":"jn","Jiao":"jp","Jie":"jc","Jin":"jb","Jing":"jg","Jiong":"jy","Jiu":"jq","Ju":"jv","Juan":"jt","Jue":"jh","Jun":"jw","Ka":"ka","Kai":"kj","Kan":"kd","Kang":"kf","Kao":"ks","Ke":"ke","Ken":"kk","Keng":"kh","Kong":"kl","Kou":"kt","Ku":"ku","Kua":"kx","Kuai":"kg","Kuan":"kr","Kuang":"kn","Kui":"ky","Kun":"kz","Kuo":"ko","La":"la","Lai":"lj","Lan":"ld","Lang":"lf","Lao":"ls","Le":"le","Lei":"lw","Leng":"lh","Li":"li","Lia":"lx","Lian":"lm","Liang":"ln","Liao":"lp","Lie":"lc","Lin":"lb","Ling":"lg","Liu":"lq","Lo":"ll","Long":"ll","Lou":"lt","Lu":"lu","Luan":"lr","Lun":"lz","Luo":"lo","Ma":"ma","Mai":"mj","Man":"md","Mang":"mf","Mao":"ms","Me":"me","Mei":"mw","Men":"mk","Meng":"mh","Mi":"mi","Mian":"mm","Miao":"mp","Mie":"mc","Min":"mb","Ming":"mg","Miu":"mq","Mo":"mo","Mou":"mt","Mu":"mu","Na":"na","Nai":"nj","Nan":"nd","Nang":"nf","Nao":"ns","Ne":"ne","Nei":"nw","Nen":"nk","Neng":"nh","Ni":"ni","Nian":"nm","Niang":"nn","Niao":"np","Nie":"nc","Nin":"nb","Ning":"ng","Niu":"nq","Nong":"nl","Nou":"nt","Nu":"nu","Nuan":"nr","Nun":"nz","Nuo":"no","Pa":"pa","Pai":"pj","Pan":"pd","Pang":"pf","Pao":"ps","Pei":"pw","Pen":"pk","Peng":"ph","Pi":"pi","Pian":"pm","Piao":"pp","Pie":"pc","Pin":"pb","Ping":"pg","Po":"po","Pou":"pt","Pu":"pu","Qi":"qk","Qia":"qs","Qian":"qm","Qiang":"qx","Qiao":"qp","Qie":"qc","Qin":"qb","Qing":"qg","Qiong":"qy","Qiu":"qq","Qu":"qv","Quan":"qt","Que":"qh","Qun":"qw","Ran":"rd","Rang":"rf","Rao":"rs","Re":"re","Ren":"rk","Reng":"rh","Ri":"ri","Rong":"rl","Rou":"rt","Ru":"ru","Rua":"rx","Ruan":"rr","Rui":"ry","Run":"rz","Ruo":"ro","Sa":"sa","Sai":"sj","San":"sd","Sang":"sf","Sao":"ss","Se":"se","Sen":"sk","Seng":"sh","Sha":"ea","Shai":"ej","Shan":"ed","Shang":"ef","Shao":"es","She":"ee","Shei":"ew","Shen":"ek","Sheng":"eh","Shi":"ei","Shou":"et","Shu":"eu","Shua":"ex","Shuai":"eg","Shuan":"er","Shuang":"en","Shui":"ey","Shun":"ez","Shuo":"eo","Si":"si","Song":"sl","Sou":"st","Su":"su","Suan":"sr","Sui":"sy","Sun":"sz","Suo":"so","Ta":"ta","Tai":"tj","Tan":"td","Tang":"tf","Tao":"ts","Te":"te","Tei":"tw","Teng":"th","Ti":"ti","Tian":"tm","Tiao":"tp","Tie":"tc","Ting":"tg","Tong":"tl","Tou":"tt","Tu":"tu","Tuan":"tr","Tui":"ty","Tun":"tz","Tuo":"to","Xi":"xi","Xia":"xx","Xian":"xm","Xiang":"xn","Xiao":"xp","Xie":"xc","Xin":"xb","Xing":"xg","Xiong":"xl","Xiu":"xq","Xu":"xv","Xuan":"xr","Xue":"xy","Xun":"xw","Za":"za","Zai":"zj","Zan":"zd","Zang":"zf","Zao":"zs","Ze":"ze","Zei":"zw","Zen":"zk","Zeng":"zh","Zha":"qa","Zhai":"fj","Zhan":"qd","Zhang":"qf","Zhao":"fs","Zhe":"fe","Zhen":"qk","Zheng":"qh","Zhi":"fi","Zhong":"fy","Zhou":"qt","Zhu":"qu","Zhua":"fx","Zhuai":"fg","Zhuan":"fr","Zhuang":"fn","Zhui":"fy","Zhun":"fz","Zhuo":"qo","Zi":"zi","Zong":"zl","Zou":"zt","Zu":"zu","Zuan":"zr","Zui":"zy","Zun":"zz","Zuo":"zo"},"DaNiu":{"Lv":"lv","Lve":"lx","Lue":"lx","Nv":"nv","Nve":"nx","Nue":"nx","A":"ea","O":"eo","E":"ee","Ai":"eh","Ei":"ew","Ao":"es","Ou":"er","An":"ed","En":"ek","Ang":"ef","Eng":"ej","Er":"eu","Yi":"yi","Ya":"ya","Yo":"yo","Ye":"ye","Yao":"ys","You":"yr","Yan":"yd","Yin":"yb","Yang":"yf","Ying":"yg","Wu":"wu","Wa":"wa","Wo":"wo","Wai":"wh","Wei":"ww","Wan":"wd","Wen":"wk","Wang":"wf","Weng":"wj","Yu":"yu","Yue":"yh","Yuan":"yj","Yun":"yw","Yong":"yl","Ba":"ba","Bai":"bh","Ban":"bd","Bang":"bf","Bao":"bs","Bei":"bw","Ben":"bk","Beng":"bj","Bi":"bi","Bian":"bc","Biang":"bn","Biao":"bm","Bie":"bp","Bin":"bb","Bing":"bg","Bo":"bo","Bu":"bu","Ca":"ca","Cai":"ch","Can":"cd","Cang":"cf","Cao":"cs","Ce":"ce","Cen":"ck","Ceng":"cj","Cha":"ia","Chai":"ih","Chan":"id","Chang":"if","Chao":"is","Che":"ie","Chen":"ik","Cheng":"ij","Chi":"ii","Chong":"il","Chou":"ir","Chu":"iu","Chua":"iq","Chuai":"ig","Chuan":"iz","Chuang":"ix","Chui":"in","Chun":"iy","Chuo":"io","Ci":"ci","Cong":"cl","Cou":"cr","Cu":"cu","Cuan":"cz","Cui":"cn","Cun":"cy","Cuo":"co","Da":"da","Dai":"dh","Dan":"dd","Dang":"df","Dao":"ds","De":"de","Dei":"dw","Den":"dk","Deng":"dj","Di":"di","Dia":"dk","Dian":"dc","Diao":"dm","Die":"dp","Ding":"dg","Diu":"dt","Dong":"dl","Dou":"dr","Du":"du","Duan":"dz","Dui":"dn","Dun":"dy","Duo":"do","Fa":"fa","Fan":"fd","Fang":"ff","Fei":"fw","Fen":"fk","Feng":"fj","Fiao":"fm","Fo":"fo","Fou":"fr","Fu":"fu","Ga":"ga","Gai":"gh","Gan":"gd","Gang":"gf","Gao":"gs","Ge":"ge","Gei":"gw","Gen":"gk","Geng":"gj","Gong":"gl","Gou":"gr","Gu":"gu","Gua":"gq","Guai":"gg","Guan":"gz","Guang":"gx","Gui":"gn","Gun":"gy","Guo":"go","Ha":"ha","Hai":"hh","Han":"hd","Hang":"hf","Hao":"hs","He":"he","Hei":"hw","Hen":"hk","Heng":"hj","Hong":"hl","Hou":"hr","Hu":"hu","Hua":"hq","Huai":"hg","Huan":"hz","Huang":"hx","Hui":"hn","Hun":"hy","Huo":"ho","Ji":"ji","Jia":"jk","Jian":"jc","Jiang":"jn","Jiao":"jm","Jie":"jp","Jin":"jb","Jing":"jg","Jiong":"jl","Jiu":"jt","Ju":"ju","Juan":"jj","Jue":"jh","Jun":"jw","Ka":"ka","Kai":"kh","Kan":"kd","Kang":"kf","Kao":"ks","Ke":"ke","Ken":"kk","Keng":"kj","Kong":"kl","Kou":"kr","Ku":"ku","Kua":"kq","Kuai":"kg","Kuan":"kz","Kuang":"kx","Kui":"kn","Kun":"ky","Kuo":"ko","La":"la","Lai":"lh","Lan":"ld","Lang":"lf","Lao":"ls","Le":"le","Lei":"lw","Leng":"lj","Li":"li","Lia":"lk","Lian":"lc","Liang":"ln","Liao":"lm","Lie":"lp","Lin":"lb","Ling":"lg","Liu":"lt","Lo":"lo","Long":"ll","Lou":"lr","Lu":"lu","Luan":"lz","Lun":"ly","Luo":"lo","Ma":"ma","Mai":"mh","Man":"md","Mang":"mf","Mao":"ms","Me":"me","Mei":"mw","Men":"mk","Meng":"mj","Mi":"mi","Mian":"mc","Miao":"mm","Mie":"mp","Min":"mb","Ming":"mg","Miu":"mt","Mo":"mo","Mou":"mr","Mu":"mu","Na":"na","Nai":"nh","Nan":"nd","Nang":"nf","Nao":"ns","Ne":"ne","Nei":"nw","Nen":"nk","Neng":"nj","Ni":"ni","Nian":"nc","Niang":"nn","Niao":"nm","Nie":"np","Nin":"nb","Ning":"ng","Niu":"nt","Nong":"nl","Nou":"nr","Nu":"nu","Nuan":"nz","Nun":"ny","Nuo":"no","Pa":"pa","Pai":"ph","Pan":"pd","Pang":"pf","Pao":"ps","Pei":"pw","Pen":"pk","Peng":"pj","Pi":"pi","Pian":"pc","Piao":"pm","Pie":"pp","Pin":"pb","Ping":"pg","Po":"po","Pou":"pr","Pu":"pu","Qi":"qi","Qia":"qk","Qian":"qc","Qiang":"qn","Qiao":"qm","Qie":"qp","Qin":"qb","Qing":"qg","Qiong":"ql","Qiu":"qt","Qu":"qu","Quan":"qj","Que":"qh","Qun":"qw","Ran":"rd","Rang":"rf","Rao":"rs","Re":"re","Ren":"rk","Reng":"rj","Ri":"ri","Rong":"rl","Rou":"rr","Ru":"ru","Rua":"rq","Ruan":"rz","Rui":"rn","Run":"ry","Ruo":"ro","Sa":"sa","Sai":"sh","San":"sd","Sang":"sf","Sao":"ss","Se":"se","Sen":"sk","Seng":"sj","Sha":"ua","Shai":"uh","Shan":"ud","Shang":"uf","Shao":"us","She":"ue","Shei":"uw","Shen":"uk","Sheng":"uj","Shi":"ui","Shou":"ur","Shu":"uu","Shua":"uq","Shuai":"ug","Shuan":"uz","Shuang":"ux","Shui":"un","Shun":"uy","Shuo":"uo","Si":"si","Song":"sl","Sou":"sr","Su":"su","Suan":"sz","Sui":"sn","Sun":"sy","Suo":"so","Ta":"ta","Tai":"th","Tan":"td","Tang":"tf","Tao":"ts","Te":"te","Tei":"tw","Teng":"tj","Ti":"ti","Tian":"tc","Tiao":"tm","Tie":"tp","Ting":"tg","Tong":"tl","Tou":"tr","Tu":"tu","Tuan":"tz","Tui":"tn","Tun":"ty","Tuo":"to","Xi":"xi","Xia":"xk","Xian":"xc","Xiang":"xn","Xiao":"xm","Xie":"xp","Xin":"xb","Xing":"xg","Xiong":"xl","Xiu":"xt","Xu":"xu","Xuan":"xj","Xue":"xh","Xun":"xw","Za":"za","Zai":"zh","Zan":"zd","Zang":"zf","Zao":"zs","Ze":"ze","Zei":"zw","Zen":"zk","Zeng":"zj","Zha":"aa","Zhai":"ah","Zhan":"ad","Zhang":"af","Zhao":"as","Zhe":"ae","Zhen":"ak","Zheng":"aj","Zhi":"ai","Zhong":"al","Zhou":"ar","Zhu":"au","Zhua":"aq","Zhuai":"ag","Zhuan":"az","Zhuang":"ax","Zhui":"an","Zhun":"ay","Zhuo":"ao","Zi":"zi","Zong":"zl","Zou":"zr","Zu":"zu","Zuan":"zz","Zui":"zn","Zun":"zy","Zuo":"zo"},"XiaoLang":{"Lv":"lx","Lve":"lb","Lue":"lb","Nv":"nx","Nve":"nb","Nue":"nb","A":"aa","O":"oo","E":"uu","Ai":"ai","Ei":"ui","Ao":"ao","Ou":"ou","An":"an","En":"un","Ang":"ah","Eng":"un","Er":"ur","Yi":"yi","Ya":"ya","Yo":"yo","Ye":"ye","Yao":"ys","You":"yr","Yan":"yj","Yin":"yd","Yang":"yh","Ying":"yv","Wu":"wu","Wa":"wa","Wo":"wo","Wai":"wk","Wei":"ww","Wan":"wj","Wen":"wm","Wang":"wh","Weng":"wn","Yu":"yu","Yue":"yb","Yuan":"yg","Yun":"yy","Yong":"yl","Ba":"ba","Bai":"bk","Ban":"bj","Bang":"bh","Bao":"bs","Bei":"bw","Ben":"bm","Beng":"bn","Bi":"bi","Bian":"bf","Biang":"bm","Biao":"bc","Bie":"bp","Bin":"bd","Bing":"bv","Bo":"bo","Bu":"bu","Ca":"ca","Cai":"ck","Can":"cj","Cang":"ch","Cao":"cs","Ce":"ce","Cen":"cm","Ceng":"cn","Cha":"ia","Chai":"ik","Chan":"ij","Chang":"ih","Chao":"is","Che":"ie","Chen":"im","Cheng":"in","Chi":"ii","Chong":"il","Chou":"ir","Chu":"iu","Chua":"if","Chuai":"iv","Chuan":"ig","Chuang":"iz","Chui":"id","Chun":"iy","Chuo":"io","Ci":"ci","Cong":"cl","Cou":"cr","Cu":"cu","Cuan":"cg","Cui":"cd","Cun":"cy","Cuo":"co","Da":"da","Dai":"dk","Dan":"dj","Dang":"dh","Dao":"ds","De":"de","Dei":"dw","Den":"dm","Deng":"dn","Di":"di","Dia":"dk","Dian":"df","Diao":"dc","Die":"dp","Ding":"dv","Diu":"dt","Dong":"dl","Dou":"dr","Du":"du","Duan":"dg","Dui":"dd","Dun":"dy","Duo":"do","Fa":"fa","Fan":"fj","Fang":"fh","Fei":"fw","Fen":"fm","Feng":"fn","Fiao":"fc","Fo":"fo","Fou":"fr","Fu":"fu","Ga":"ga","Gai":"gk","Gan":"gj","Gang":"gh","Gao":"gs","Ge":"ge","Gei":"gw","Gen":"gm","Geng":"gn","Gong":"gl","Gou":"gr","Gu":"gu","Gua":"gf","Guai":"gv","Guan":"gg","Guang":"gz","Gui":"gd","Gun":"gy","Guo":"go","Ha":"ha","Hai":"hk","Han":"hj","Hang":"hh","Hao":"hs","He":"he","Hei":"hw","Hen":"hm","Heng":"hn","Hong":"hl","Hou":"hr","Hu":"hu","Hua":"hf","Huai":"hv","Huan":"hg","Huang":"hz","Hui":"hd","Hun":"hy","Huo":"ho","Ji":"ji","Jia":"jk","Jian":"jf","Jiang":"jm","Jiao":"jc","Jie":"jp","Jin":"jd","Jing":"jv","Jiong":"jj","Jiu":"jt","Ju":"ju","Juan":"jg","Jue":"jb","Jun":"jy","Ka":"ka","Kai":"kk","Kan":"kj","Kang":"kh","Kao":"ks","Ke":"ke","Ken":"km","Keng":"kn","Kong":"kl","Kou":"kr","Ku":"ku","Kua":"kf","Kuai":"kv","Kuan":"kg","Kuang":"kz","Kui":"kd","Kun":"ky","Kuo":"ko","La":"la","Lai":"lk","Lan":"lj","Lang":"lh","Lao":"ls","Le":"le","Lei":"lw","Leng":"ln","Li":"li","Lia":"lk","Lian":"lf","Liang":"lm","Liao":"lc","Lie":"lp","Lin":"ld","Ling":"lv","Liu":"lt","Lo":"lo","Long":"ll","Lou":"lr","Lu":"lu","Luan":"lg","Lun":"ly","Luo":"lo","Ma":"ma","Mai":"mk","Man":"mj","Mang":"mh","Mao":"ms","Me":"me","Mei":"mw","Men":"mm","Meng":"mn","Mi":"mi","Mian":"mf","Miao":"mc","Mie":"mp","Min":"md","Ming":"mv","Miu":"mt","Mo":"mo","Mou":"mr","Mu":"mu","Na":"na","Nai":"nk","Nan":"nj","Nang":"nh","Nao":"ns","Ne":"ne","Nei":"nw","Nen":"nm","Neng":"nn","Ni":"ni","Nian":"nf","Niang":"nm","Niao":"nc","Nie":"np","Nin":"nd","Ning":"nv","Niu":"nt","Nong":"nl","Nou":"nr","Nu":"nu","Nuan":"ng","Nun":"ny","Nuo":"no","Pa":"pa","Pai":"pk","Pan":"pj","Pang":"ph","Pao":"ps","Pei":"pw","Pen":"pm","Peng":"pn","Pi":"pi","Pian":"pf","Piao":"pc","Pie":"pp","Pin":"pd","Ping":"pv","Po":"po","Pou":"pr","Pu":"pu","Qi":"qi","Qia":"qk","Qian":"qf","Qiang":"qm","Qiao":"qc","Qie":"qp","Qin":"qd","Qing":"qv","Qiong":"qj","Qiu":"qt","Qu":"qu","Quan":"qg","Que":"qb","Qun":"qy","Ran":"rj","Rang":"rh","Rao":"rs","Re":"re","Ren":"rm","Reng":"rn","Ri":"ri","Rong":"rl","Rou":"rr","Ru":"ru","Rua":"rf","Ruan":"rg","Rui":"rd","Run":"ry","Ruo":"ro","Sa":"sa","Sai":"sk","San":"sj","Sang":"sh","Sao":"ss","Se":"se","Sen":"sm","Seng":"sn","Sha":"va","Shai":"vk","Shan":"vj","Shang":"vh","Shao":"vs","She":"ve","Shei":"vw","Shen":"vm","Sheng":"vn","Shi":"vi","Shou":"vr","Shu":"vu","Shua":"vf","Shuai":"vv","Shuan":"vg","Shuang":"vz","Shui":"vd","Shun":"vy","Shuo":"vo","Si":"si","Song":"sl","Sou":"sr","Su":"su","Suan":"sg","Sui":"sd","Sun":"sy","Suo":"so","Ta":"ta","Tai":"tk","Tan":"tj","Tang":"th","Tao":"ts","Te":"te","Tei":"tw","Teng":"tn","Ti":"ti","Tian":"tf","Tiao":"tc","Tie":"tp","Ting":"tv","Tong":"tl","Tou":"tr","Tu":"tu","Tuan":"tg","Tui":"td","Tun":"ty","Tuo":"to","Xi":"xi","Xia":"xk","Xian":"xf","Xiang":"xm","Xiao":"xc","Xie":"xp","Xin":"xd","Xing":"xv","Xiong":"xj","Xiu":"xt","Xu":"xu","Xuan":"xg","Xue":"xb","Xun":"xy","Za":"za","Zai":"zk","Zan":"zj","Zang":"zh","Zao":"zs","Ze":"ze","Zei":"zw","Zen":"zm","Zeng":"zn","Zha":"ea","Zhai":"ek","Zhan":"ej","Zhang":"eh","Zhao":"es","Zhe":"ee","Zhen":"em","Zheng":"en","Zhi":"ei","Zhong":"el","Zhou":"er","Zhu":"eu","Zhua":"ef","Zhuai":"ev","Zhuan":"eg","Zhuang":"ez","Zhui":"ed","Zhun":"ey","Zhuo":"eo","Zi":"zi","Zong":"zl","Zou":"zr","Zu":"zu","Zuan":"zg","Zui":"zd","Zun":"zy","Zuo":"zo"}}
\ No newline at end of file
From 4fb2e3d14e856cb6917204ce824d89b3cdf8de9c Mon Sep 17 00:00:00 2001
From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Sat, 14 Jun 2025 16:33:48 +0800
Subject: [PATCH 1546/1697] Fix translation mapping logic
---
Flow.Launcher.Infrastructure/PinyinAlphabet.cs | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
index 6a2cd1e66..36f007f39 100644
--- a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
+++ b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
@@ -99,13 +99,19 @@ namespace Flow.Launcher.Infrastructure
{
if (content[i] >= 0x3400 && content[i] <= 0x9FD5)
{
- string dp = _settings.UseDoublePinyin ? ToDoublePin(resultList[i]) : resultList[i];
- map.AddNewIndex(i, resultBuilder.Length, dp.Length + 1);
+ string translated = _settings.UseDoublePinyin ? ToDoublePin(resultList[i]) : resultList[i];
if (previousIsChinese)
{
+ map.AddNewIndex(i, resultBuilder.Length, translated.Length + 1);
resultBuilder.Append(' ');
+ resultBuilder.Append(translated);
+ }
+ else
+ {
+ map.AddNewIndex(i, resultBuilder.Length, translated.Length);
+ resultBuilder.Append(translated);
+ previousIsChinese = true;
}
- resultBuilder.Append(dp);
}
else
{
From 7784fe439c003636ac73e13b63b8024e6461ff03 Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Sat, 14 Jun 2025 22:25:55 +1000
Subject: [PATCH 1547/1697] Merge release v1.20.1 back into dev
---
Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj | 8 ++++----
appveyor.yml | 4 ++--
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj b/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj
index 4a26cec95..4a49e9589 100644
--- a/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj
+++ b/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj
@@ -14,10 +14,10 @@
- 4.5.0
- 4.5.0
- 4.5.0
- 4.5.0
+ 4.6.0
+ 4.6.0
+ 4.6.0
+ 4.6.0
Flow.Launcher.Plugin
Flow-Launcher
MIT
diff --git a/appveyor.yml b/appveyor.yml
index 8fba05252..b38e5bb1a 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,4 +1,4 @@
-version: '1.20.0.{build}'
+version: '1.20.1.{build}'
init:
- ps: |
@@ -60,7 +60,7 @@ deploy:
- provider: NuGet
artifact: Plugin nupkg
api_key:
- secure: sCSd5JWgdzJWDa9kpqECut5ACPKZqcoxKU8ERKC00k7VIjig3/+nFV5zzTcGb0w3
+ secure: en+/GPSgfUVARoX0+lOeAAlbzvcCZAyBeVQaNq1AeXuRjjHgMwhBnt0PHVJXOepS
on:
branch: master
From c06fdb9134da07c0a6ad989847f3196e5d8f82db Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 14 Jun 2025 20:35:09 +0800
Subject: [PATCH 1548/1697] Set topmost default value to false
---
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 975609e0f..33f7c5fc2 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -383,7 +383,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
public bool LeaveCmdOpen { get; set; }
public bool HideWhenDeactivated { get; set; } = true;
- private bool _showAtTopmost = true;
+ private bool _showAtTopmost = false;
public bool ShowAtTopmost
{
get => _showAtTopmost;
From d9a30f6450705d3aed34d8e6a87adf8e19de7f58 Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Sat, 14 Jun 2025 22:56:08 +1000
Subject: [PATCH 1549/1697] add skip build on tag
---
appveyor.yml | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/appveyor.yml b/appveyor.yml
index b38e5bb1a..a430b28f4 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,5 +1,8 @@
version: '1.20.1.{build}'
+# Do not build on tags because we create a release on merge to master. Otherwise will upload artifacts twice changing the hash, as well as triggering duplicate GitHub release action & NuGet deployments.
+skip_tags: true
+
init:
- ps: |
$version = new-object System.Version $env:APPVEYOR_BUILD_VERSION
@@ -14,7 +17,6 @@ init:
cache:
- '%USERPROFILE%\.nuget\packages -> **.sln, **.csproj' # preserve nuget folder (packages) unless the solution or projects change
-
assembly_info:
patch: true
file: SolutionAssemblyInfo.cs
From f30c6fc577c9fd60ee2de0db6f275847c2ff8f4c Mon Sep 17 00:00:00 2001
From: DB P
Date: Sat, 14 Jun 2025 22:19:31 +0900
Subject: [PATCH 1550/1697] Modified strings and added BoolNegationConverter
---
.../Converters/BoolNegationConverter.cs | 23 +++++++++++++++
Flow.Launcher/Languages/en.xaml | 4 +--
.../Views/SettingsPaneGeneral.xaml | 28 ++++++++++---------
3 files changed, 40 insertions(+), 15 deletions(-)
create mode 100644 Flow.Launcher/Converters/BoolNegationConverter.cs
diff --git a/Flow.Launcher/Converters/BoolNegationConverter.cs b/Flow.Launcher/Converters/BoolNegationConverter.cs
new file mode 100644
index 000000000..50a5c0f34
--- /dev/null
+++ b/Flow.Launcher/Converters/BoolNegationConverter.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Globalization;
+using System.Windows.Data;
+
+namespace Flow.Launcher.Converters
+{
+ public class BoolNegationConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (value is bool b)
+ return !b;
+ return value;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (value is bool b)
+ return !b;
+ return value;
+ }
+ }
+}
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index f7f8dfd42..4df6b3155 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -131,8 +131,8 @@
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.
- Show Search Window at Topmost
- Show search window above other windows
+ Keep on top
+ Keeps the search window on top even after it loses focus.
Search Plugin
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
index e8ae0dc3c..ae1648076 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
@@ -17,6 +17,7 @@
mc:Ignorable="d">
+
-
-
+
+
-
+
+
+
+
+
-
-
-
From 4b6231ba8b807a62cd1fef17d370b3bd7b0fb31a Mon Sep 17 00:00:00 2001
From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Sat, 14 Jun 2025 22:22:25 +0800
Subject: [PATCH 1551/1697] Extract methods for readability
---
.../PinyinAlphabet.cs | 33 +++++++++++--------
1 file changed, 19 insertions(+), 14 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
index 36f007f39..37b7bb8c3 100644
--- a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
+++ b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
@@ -31,12 +31,27 @@ namespace Flow.Launcher.Infrastructure
if (e.PropertyName == nameof(Settings.UseDoublePinyin) ||
e.PropertyName == nameof(Settings.DoublePinyinSchema))
{
- LoadDoublePinyinTable();
- _pinyinCache.Clear();
+ Reload();
}
};
}
+ public void Reload()
+ {
+ LoadDoublePinyinTable();
+ _pinyinCache.Clear();
+ }
+
+ private void CreateDoublePinyinTableFromStream(Stream jsonStream)
+ {
+ Dictionary> table = JsonSerializer.Deserialize>>(jsonStream);
+ if (!table.TryGetValue(_settings.DoublePinyinSchema, out var value))
+ {
+ throw new InvalidOperationException("DoublePinyinSchema is invalid or double pinyin table is broken.");
+ }
+ currentDoublePinyinTable = new ReadOnlyDictionary(value);
+ }
+
private void LoadDoublePinyinTable()
{
if (_settings.UseDoublePinyin)
@@ -45,12 +60,7 @@ namespace Flow.Launcher.Infrastructure
try
{
using var fs = File.OpenRead(tablePath);
- Dictionary> table = JsonSerializer.Deserialize>>(fs);
- if (!table.TryGetValue(_settings.DoublePinyinSchema, out var value))
- {
- throw new InvalidOperationException("DoublePinyinSchema is invalid.");
- }
- currentDoublePinyinTable = new ReadOnlyDictionary(value);
+ CreateDoublePinyinTableFromStream(fs);
}
catch (System.Exception e)
{
@@ -73,7 +83,7 @@ namespace Flow.Launcher.Infrastructure
public (string translation, TranslationMapping map) Translate(string content)
{
- if (!_settings.ShouldUsePinyin)
+ if (!_settings.ShouldUsePinyin || !WordsHelper.HasChinese(content))
return (content, null);
return _pinyinCache.TryGetValue(content, out var value)
@@ -83,11 +93,6 @@ namespace Flow.Launcher.Infrastructure
private (string translation, TranslationMapping map) BuildCacheFromContent(string content)
{
- if (!WordsHelper.HasChinese(content))
- {
- return (content, null);
- }
-
var resultList = WordsHelper.GetPinyinList(content);
var resultBuilder = new StringBuilder();
From 27daffe515319317682afb263e532fdd11e221b2 Mon Sep 17 00:00:00 2001
From: DB P
Date: Sat, 14 Jun 2025 23:26:08 +0900
Subject: [PATCH 1552/1697] Revert "Modified strings and added
BoolNegationConverter"
This reverts commit f30c6fc577c9fd60ee2de0db6f275847c2ff8f4c.
---
.../Converters/BoolNegationConverter.cs | 23 ---------------
Flow.Launcher/Languages/en.xaml | 4 +--
.../Views/SettingsPaneGeneral.xaml | 28 +++++++++----------
3 files changed, 15 insertions(+), 40 deletions(-)
delete mode 100644 Flow.Launcher/Converters/BoolNegationConverter.cs
diff --git a/Flow.Launcher/Converters/BoolNegationConverter.cs b/Flow.Launcher/Converters/BoolNegationConverter.cs
deleted file mode 100644
index 50a5c0f34..000000000
--- a/Flow.Launcher/Converters/BoolNegationConverter.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using System;
-using System.Globalization;
-using System.Windows.Data;
-
-namespace Flow.Launcher.Converters
-{
- public class BoolNegationConverter : IValueConverter
- {
- public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
- {
- if (value is bool b)
- return !b;
- return value;
- }
-
- public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
- {
- if (value is bool b)
- return !b;
- return value;
- }
- }
-}
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 4df6b3155..f7f8dfd42 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -131,8 +131,8 @@
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.
- Keep on top
- Keeps the search window on top even after it loses focus.
+ Show Search Window at Topmost
+ Show search window above other windows
Search Plugin
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
index ae1648076..e8ae0dc3c 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
@@ -17,7 +17,6 @@
mc:Ignorable="d">
-
-
-
-
+
-
-
-
-
-
+
+
+
+
From 4c7f966e7c2af0ee7d231a0422dc3b8831fafc7d Mon Sep 17 00:00:00 2001
From: DB P
Date: Sat, 14 Jun 2025 23:55:34 +0900
Subject: [PATCH 1553/1697] UI improvement and text update - en.xaml: Updated
"showAtTopmost" and tooltip text - SettingsPaneGeneral.xaml: Added "Hide
Notify Icon" card and updated icon - Adjusted card group margins
---
Flow.Launcher/Languages/en.xaml | 4 ++--
Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml | 6 ++++--
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index f7f8dfd42..bd4cbd282 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -131,8 +131,8 @@
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.
- Show Search Window at Topmost
- Show search window above other windows
+ Show Search Window at Foremost
+ Overrides other programs' 'Always on Top' setting and displays Flow in the foremost position.
Search Plugin
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
index e8ae0dc3c..7f8555d65 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
@@ -70,6 +70,7 @@
OnContent="{DynamicResource enable}" />
+
+
-
+
Date: Sun, 15 Jun 2025 21:21:46 +0800
Subject: [PATCH 1554/1697] Fix one more whitespace after commands
---
Plugins/Flow.Launcher.Plugin.Shell/Main.cs | 24 +++++++++++++++++-----
1 file changed, 19 insertions(+), 5 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
index d0add9f31..37f382ad1 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
@@ -194,10 +194,12 @@ namespace Flow.Launcher.Plugin.Shell
var workingDirectory = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
var runAsAdministratorArg = !runAsAdministrator && !_settings.RunAsAdministrator ? "" : "runas";
- ProcessStartInfo info = new()
+ var info = new ProcessStartInfo()
{
- Verb = runAsAdministratorArg, WorkingDirectory = workingDirectory,
+ Verb = runAsAdministratorArg,
+ WorkingDirectory = workingDirectory,
};
+ var notifyStr = Context.API.GetTranslation("flowlauncher_plugin_cmd_press_any_key_to_close");
switch (_settings.Shell)
{
case Shell.Cmd:
@@ -212,7 +214,11 @@ namespace Flow.Launcher.Plugin.Shell
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 {notifyStr} && pause > nul /c" :
+ "")}");
break;
}
@@ -238,7 +244,11 @@ namespace Flow.Launcher.Plugin.Shell
else
{
info.ArgumentList.Add("-Command");
- info.ArgumentList.Add($"{command}{addedCharacter}; {(_settings.CloseShellAfterPress ? $"Write-Host '{Context.API.GetTranslation("flowlauncher_plugin_cmd_press_any_key_to_close")}'{addedCharacter}; [System.Console]::ReadKey(){addedCharacter}; exit" : "")}");
+ info.ArgumentList.Add(
+ $"{command}{addedCharacter};" +
+ $"{(_settings.CloseShellAfterPress ?
+ $" Write-Host '{notifyStr}'{addedCharacter}; [System.Console]::ReadKey(){addedCharacter}; exit" :
+ "")}");
}
break;
}
@@ -262,7 +272,11 @@ namespace Flow.Launcher.Plugin.Shell
info.ArgumentList.Add("-NoExit");
}
info.ArgumentList.Add("-Command");
- info.ArgumentList.Add($"{command}{addedCharacter}; {(_settings.CloseShellAfterPress ? $"Write-Host '{Context.API.GetTranslation("flowlauncher_plugin_cmd_press_any_key_to_close")}'{addedCharacter}; [System.Console]::ReadKey(){addedCharacter}; exit" : "")}");
+ info.ArgumentList.Add(
+ $"{command}{addedCharacter};" +
+ $"{(_settings.CloseShellAfterPress ?
+ $" Write-Host '{notifyStr}'{addedCharacter}; [System.Console]::ReadKey(){addedCharacter}; exit" :
+ "")}");
break;
}
From 89214fb58a0844854a99fcd8ac35a185436caa6d Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 16 Jun 2025 12:38:31 +0800
Subject: [PATCH 1555/1697] Improve code quality
---
Plugins/Flow.Launcher.Plugin.Shell/Main.cs | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
index 37f382ad1..a51aadec7 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
@@ -200,6 +200,7 @@ namespace Flow.Launcher.Plugin.Shell
WorkingDirectory = workingDirectory,
};
var notifyStr = Context.API.GetTranslation("flowlauncher_plugin_cmd_press_any_key_to_close");
+ var addedCharacter = _settings.UseWindowsTerminal ? "\\" : "";
switch (_settings.Shell)
{
case Shell.Cmd:
@@ -213,9 +214,16 @@ namespace Flow.Launcher.Plugin.Shell
{
info.FileName = "cmd.exe";
}
-
+ if (_settings.LeaveShellOpen)
+ {
+ info.ArgumentList.Add("/k");
+ }
+ else
+ {
+ info.ArgumentList.Add("/c");
+ }
info.ArgumentList.Add(
- $"{(_settings.LeaveShellOpen ? "/k" : "/c")} {command}" +
+ $"{command}" +
$"{(_settings.CloseShellAfterPress ?
$" && echo {notifyStr} && pause > nul /c" :
"")}");
@@ -226,7 +234,6 @@ namespace Flow.Launcher.Plugin.Shell
{
// Using just a ; doesn't work with wt, as it's used to create a new tab for the terminal window
// \\ must be escaped for it to work properly, or breaking it into multiple arguments
- var addedCharacter = _settings.UseWindowsTerminal ? "\\" : "";
if (_settings.UseWindowsTerminal)
{
info.FileName = "wt.exe";
@@ -257,7 +264,6 @@ namespace Flow.Launcher.Plugin.Shell
{
// Using just a ; doesn't work with wt, as it's used to create a new tab for the terminal window
// \\ must be escaped for it to work properly, or breaking it into multiple arguments
- var addedCharacter = _settings.UseWindowsTerminal ? "\\" : "";
if (_settings.UseWindowsTerminal)
{
info.FileName = "wt.exe";
From 30d10bb37f6fb903f4d7c9cfbea82571eb9372b7 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 16 Jun 2025 21:11:50 +0800
Subject: [PATCH 1556/1697] Add try catch for register key check
---
Flow.Launcher/Helper/WindowsMediaPlayerHelper.cs | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/Helper/WindowsMediaPlayerHelper.cs b/Flow.Launcher/Helper/WindowsMediaPlayerHelper.cs
index 9d2046972..2da2cf034 100644
--- a/Flow.Launcher/Helper/WindowsMediaPlayerHelper.cs
+++ b/Flow.Launcher/Helper/WindowsMediaPlayerHelper.cs
@@ -1,11 +1,19 @@
using Microsoft.Win32;
namespace Flow.Launcher.Helper;
+
internal static class WindowsMediaPlayerHelper
{
internal static bool IsWindowsMediaPlayerInstalled()
{
- using var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\MediaPlayer");
- return key?.GetValue("Installation Directory") != null;
+ try
+ {
+ using var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\MediaPlayer");
+ return key?.GetValue("Installation Directory") != null;
+ }
+ catch
+ {
+ return false;
+ }
}
}
From be15b836fc631a74bc8cba0a6139e424bef0039c Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 16 Jun 2025 21:12:06 +0800
Subject: [PATCH 1557/1697] Add blank line
---
Flow.Launcher/App.xaml.cs | 1 +
1 file changed, 1 insertion(+)
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 69aa834ca..5df1f88ae 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -56,6 +56,7 @@ namespace Flow.Launcher
{
// Initialize settings
_settings.WMPInstalled = WindowsMediaPlayerHelper.IsWindowsMediaPlayerInstalled();
+
// Configure the dependency injection container
try
{
From 9e24d2cb9191df33fafee41284a27dd4dfb14874 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 16 Jun 2025 21:31:51 +0800
Subject: [PATCH 1558/1697] Output log info
---
Flow.Launcher/Helper/WindowsMediaPlayerHelper.cs | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/Helper/WindowsMediaPlayerHelper.cs b/Flow.Launcher/Helper/WindowsMediaPlayerHelper.cs
index 2da2cf034..b05409de2 100644
--- a/Flow.Launcher/Helper/WindowsMediaPlayerHelper.cs
+++ b/Flow.Launcher/Helper/WindowsMediaPlayerHelper.cs
@@ -1,9 +1,12 @@
-using Microsoft.Win32;
+using System;
+using Microsoft.Win32;
namespace Flow.Launcher.Helper;
internal static class WindowsMediaPlayerHelper
{
+ private static readonly string ClassName = nameof(WindowsMediaPlayerHelper);
+
internal static bool IsWindowsMediaPlayerInstalled()
{
try
@@ -11,8 +14,9 @@ internal static class WindowsMediaPlayerHelper
using var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\MediaPlayer");
return key?.GetValue("Installation Directory") != null;
}
- catch
+ catch (Exception e)
{
+ App.API.LogException(ClassName, "Failed to check if Windows Media Player is installed", e);
return false;
}
}
From f3ce6975c9f465c772cf0c16fb1cc2e76268eb5c Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 17 Jun 2025 13:28:04 +0800
Subject: [PATCH 1559/1697] Fix tab sequence
---
Flow.Launcher/CustomShortcutSetting.xaml | 26 +++++++++++++-----------
1 file changed, 14 insertions(+), 12 deletions(-)
diff --git a/Flow.Launcher/CustomShortcutSetting.xaml b/Flow.Launcher/CustomShortcutSetting.xaml
index d8623753f..5185354e7 100644
--- a/Flow.Launcher/CustomShortcutSetting.xaml
+++ b/Flow.Launcher/CustomShortcutSetting.xaml
@@ -118,24 +118,26 @@
FontSize="14"
Text="{DynamicResource customShortcutExpansion}" />
-
-
+
+
+
+
+
-
+
+
From 4dd783360389b78e9c046b04a1d77aea023687e7 Mon Sep 17 00:00:00 2001
From: DB P
Date: Tue, 17 Jun 2025 16:45:44 +0900
Subject: [PATCH 1560/1697] UI improvements and file/folder selection feature
added - Updated "Name" and "Path" keys and added new keys in en.xaml. -
Modified QuickAccessLinkSettings.xaml: increased Window height and improved
layout using Grid structure. - Added new UI elements: implemented radio
buttons for file/folder selection. - Added and initialized QuickAccessLinks
property in QuickAccessLinkSettings.xaml.cs. - Added file selection dialog in
SelectPath_OnClick method. - Added IsFileSelected and IsFolderSelected
properties to implement selection functionality.
---
.../Languages/en.xaml | 7 +-
.../Views/QuickAccessLinkSettings.xaml | 135 +++++++++++-------
.../Views/QuickAccessLinkSettings.xaml.cs | 42 +++++-
3 files changed, 126 insertions(+), 58 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
index 7d0a553a4..2e0f6a67d 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
@@ -98,8 +98,11 @@
Delete
Permanently delete current file
Permanently delete current folder
- Path:
- Name:
+ Name
+ Type
+ Path
+ File
+ Folder
Delete the selected
Run as different user
Run the selected using a different user account
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml
index e9ba53618..f35633bc5 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml
@@ -1,22 +1,23 @@
-
-
-
-
+
+
+
+
@@ -58,55 +59,91 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
-
-
+ IsReadOnly="True"
+ Text="{Binding SelectedPath, Mode=TwoWay}" />
-
-
+ Click="SelectPath_OnClick"
+ Content="{DynamicResource select}" />
+
@@ -134,4 +171,4 @@
-
+
\ No newline at end of file
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
index 36a00e9e5..1e52ea81e 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
@@ -49,9 +49,9 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
private bool IsEdit { get; }
private AccessLink SelectedAccessLink { get; }
-
+
public ObservableCollection QuickAccessLinks { get; }
-
+
public QuickAccessLinkSettings(ObservableCollection quickAccessLinks)
{
IsEdit = false;
@@ -96,7 +96,7 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
}
// If editing, update the existing link
- if (IsEdit)
+ if (IsEdit)
{
if (SelectedAccessLink == null) return;
@@ -130,12 +130,30 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
private void SelectPath_OnClick(object commandParameter, RoutedEventArgs e)
{
- var folderBrowserDialog = new FolderBrowserDialog();
+ // Open file or folder selection dialog based on the selected radio button
+ if (IsFileSelected)
+ {
+ var openFileDialog = new Microsoft.Win32.OpenFileDialog
+ {
+ Multiselect = false,
+ CheckFileExists = true,
+ CheckPathExists = true
+ };
- if (folderBrowserDialog.ShowDialog() != System.Windows.Forms.DialogResult.OK)
- return;
+ if (openFileDialog.ShowDialog() == true)
+ {
+ SelectedPath = openFileDialog.FileName;
+ }
+ }
+ else // Folder selection
+ {
+ var folderBrowserDialog = new FolderBrowserDialog();
- SelectedPath = folderBrowserDialog.SelectedPath;
+ if (folderBrowserDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
+ {
+ SelectedPath = folderBrowserDialog.SelectedPath;
+ }
+ }
}
public event PropertyChangedEventHandler PropertyChanged;
@@ -144,4 +162,14 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
+
+ public bool IsFileSelected { get; set; }
+ public bool IsFolderSelected { get; set; }
+
+ public QuickAccessLinkSettings()
+ {
+ IsFolderSelected = true; // Default to folder selection
+ InitializeComponent();
+ DataContext = this;
+ }
}
From 52da1c97d998e5901e3699bc11a40d753da2de5f Mon Sep 17 00:00:00 2001
From: DB P
Date: Tue, 17 Jun 2025 16:50:42 +0900
Subject: [PATCH 1561/1697] Adjust Button Size
---
.../Views/QuickAccessLinkSettings.xaml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml
index f35633bc5..e977a72c2 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml
@@ -155,14 +155,14 @@
From 42dc582ec1fd5bc06aedf75030ec34e0227cd315 Mon Sep 17 00:00:00 2001
From: DB P
Date: Tue, 17 Jun 2025 17:07:02 +0900
Subject: [PATCH 1562/1697] Change default value to file
---
.../Views/QuickAccessLinkSettings.xaml.cs | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
index 1e52ea81e..1cfc3b6c0 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
@@ -163,13 +163,11 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
- public bool IsFileSelected { get; set; }
- public bool IsFolderSelected { get; set; }
+ public bool IsFileSelected { get; set; } = true; // Default to File
+ public bool IsFolderSelected { get; set; }
public QuickAccessLinkSettings()
{
- IsFolderSelected = true; // Default to folder selection
InitializeComponent();
- DataContext = this;
}
}
From 12b51eb2392fae9f251476dbd29a69df9291abd8 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 17 Jun 2025 16:31:11 +0800
Subject: [PATCH 1563/1697] Code quality
---
.../Views/QuickAccessLinkSettings.xaml.cs | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
index 1cfc3b6c0..7cc46434f 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
@@ -47,6 +47,9 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
}
}
+ public bool IsFileSelected { get; set; } = true; // Default to File
+ public bool IsFolderSelected { get; set; }
+
private bool IsEdit { get; }
private AccessLink SelectedAccessLink { get; }
@@ -162,12 +165,4 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
-
- public bool IsFileSelected { get; set; } = true; // Default to File
- public bool IsFolderSelected { get; set; }
-
- public QuickAccessLinkSettings()
- {
- InitializeComponent();
- }
}
From 76972d38496e95d32f4f7aeea3bb35bf1bba6993 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 17 Jun 2025 16:31:25 +0800
Subject: [PATCH 1564/1697] Use form dialog
---
.../Views/QuickAccessLinkSettings.xaml.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
index 7cc46434f..445c128e2 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
@@ -136,7 +136,7 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
// Open file or folder selection dialog based on the selected radio button
if (IsFileSelected)
{
- var openFileDialog = new Microsoft.Win32.OpenFileDialog
+ var openFileDialog = new OpenFileDialog
{
Multiselect = false,
CheckFileExists = true,
From 1c652320e6d1186fdd5dbe186bcac0bf731bb33a Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 17 Jun 2025 16:32:18 +0800
Subject: [PATCH 1565/1697] Get access link type
---
.../Views/QuickAccessLinkSettings.xaml.cs | 54 +++++++++++++++----
1 file changed, 45 insertions(+), 9 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
index 445c128e2..c520c2a39 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
@@ -6,12 +6,15 @@ using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Forms;
using Flow.Launcher.Plugin.Explorer.Helper;
+using Flow.Launcher.Plugin.Explorer.Search;
using Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks;
namespace Flow.Launcher.Plugin.Explorer.Views;
public partial class QuickAccessLinkSettings : INotifyPropertyChanged
{
+ private ResultType _accessLinkType = ResultType.Folder;
+
private string _selectedPath;
public string SelectedPath
{
@@ -25,6 +28,7 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
if (string.IsNullOrEmpty(_selectedName))
{
SelectedName = _selectedPath.GetPathName();
+ _accessLinkType = GetResultType(_selectedPath);
}
}
}
@@ -67,6 +71,7 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
IsEdit = true;
_selectedName = selectedAccessLink.Name;
_selectedPath = selectedAccessLink.Path;
+ _accessLinkType = GetResultType(_selectedPath);
SelectedAccessLink = selectedAccessLink;
QuickAccessLinks = quickAccessLinks;
InitializeComponent();
@@ -109,7 +114,7 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
var updatedLink = new AccessLink
{
Name = SelectedName,
- Type = SelectedAccessLink.Type,
+ Type = _accessLinkType,
Path = SelectedPath
};
QuickAccessLinks[index] = updatedLink;
@@ -123,6 +128,7 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
var newAccessLink = new AccessLink
{
Name = SelectedName,
+ Type = _accessLinkType,
Path = SelectedPath
};
QuickAccessLinks.Add(newAccessLink);
@@ -143,19 +149,49 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
CheckPathExists = true
};
- if (openFileDialog.ShowDialog() == true)
- {
- SelectedPath = openFileDialog.FileName;
- }
+ if (openFileDialog.ShowDialog() != System.Windows.Forms.DialogResult.OK ||
+ string.IsNullOrEmpty(openFileDialog.FileName))
+ return;
+
+ SelectedPath = openFileDialog.FileName;
}
else // Folder selection
{
- var folderBrowserDialog = new FolderBrowserDialog();
-
- if (folderBrowserDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
+ var folderBrowserDialog = new FolderBrowserDialog
{
- SelectedPath = folderBrowserDialog.SelectedPath;
+ ShowNewFolderButton = true
+ };
+
+ if (folderBrowserDialog.ShowDialog() != System.Windows.Forms.DialogResult.OK ||
+ string.IsNullOrEmpty(folderBrowserDialog.SelectedPath))
+ return;
+
+ SelectedPath = folderBrowserDialog.SelectedPath;
+ }
+ }
+
+ private static ResultType GetResultType(string path)
+ {
+ // Check if the path is a file or folder
+ if (System.IO.File.Exists(path))
+ {
+ return ResultType.File;
+ }
+ else if (System.IO.Directory.Exists(path))
+ {
+ if (string.Equals(System.IO.Path.GetPathRoot(path), path, StringComparison.OrdinalIgnoreCase))
+ {
+ return ResultType.Volume;
}
+ else
+ {
+ return ResultType.Folder;
+ }
+ }
+ else
+ {
+ // This should not happen, but just in case, we assume it's a folder
+ return ResultType.Folder;
}
}
From af92bda06dbcd34bebfdf70e8f63d60e355b64b2 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 17 Jun 2025 16:33:25 +0800
Subject: [PATCH 1566/1697] Initialize default access link type
---
.../Views/QuickAccessLinkSettings.xaml.cs | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
index c520c2a39..798d26b42 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
@@ -71,7 +71,9 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
IsEdit = true;
_selectedName = selectedAccessLink.Name;
_selectedPath = selectedAccessLink.Path;
- _accessLinkType = GetResultType(_selectedPath);
+ _accessLinkType = GetResultType(_selectedPath); // Initialize link type
+ IsFileSelected = selectedAccessLink.Type == ResultType.File; // Initialize default selection
+ IsFolderSelected = !IsFileSelected;
SelectedAccessLink = selectedAccessLink;
QuickAccessLinks = quickAccessLinks;
InitializeComponent();
From b28bb38f52b0714c603c85ee48de4250b45ce4ce Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 17 Jun 2025 16:34:43 +0800
Subject: [PATCH 1567/1697] Add new link if selected link is null
---
.../Views/QuickAccessLinkSettings.xaml.cs | 35 ++++++++++++-------
1 file changed, 23 insertions(+), 12 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
index 798d26b42..a94aa6b02 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
@@ -108,24 +108,35 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
// If editing, update the existing link
if (IsEdit)
{
- if (SelectedAccessLink == null) return;
-
- var index = QuickAccessLinks.IndexOf(SelectedAccessLink);
- if (index >= 0)
+ if (SelectedAccessLink != null)
{
- var updatedLink = new AccessLink
+ var index = QuickAccessLinks.IndexOf(SelectedAccessLink);
+ if (index >= 0)
{
- Name = SelectedName,
- Type = _accessLinkType,
- Path = SelectedPath
- };
- QuickAccessLinks[index] = updatedLink;
+ var updatedLink = new AccessLink
+ {
+ Name = SelectedName,
+ Type = _accessLinkType,
+ Path = SelectedPath
+ };
+ QuickAccessLinks[index] = updatedLink;
+ }
+ DialogResult = true;
+ Close();
+ }
+ // Add a new one if the selected access link is null (should not happen in edit mode, but just in case)
+ else
+ {
+ AddNewAccessLink();
}
- DialogResult = true;
- Close();
}
// Otherwise, add a new one
else
+ {
+ AddNewAccessLink();
+ }
+
+ void AddNewAccessLink()
{
var newAccessLink = new AccessLink
{
From 054ee4cdbe779bca503732f8694867ac855aaa07 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 17 Jun 2025 16:37:17 +0800
Subject: [PATCH 1568/1697] Default to folder
---
.../Views/QuickAccessLinkSettings.xaml.cs | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
index a94aa6b02..7b4d92bf5 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
@@ -13,8 +13,6 @@ namespace Flow.Launcher.Plugin.Explorer.Views;
public partial class QuickAccessLinkSettings : INotifyPropertyChanged
{
- private ResultType _accessLinkType = ResultType.Folder;
-
private string _selectedPath;
public string SelectedPath
{
@@ -51,14 +49,16 @@ public partial class QuickAccessLinkSettings : INotifyPropertyChanged
}
}
- public bool IsFileSelected { get; set; } = true; // Default to File
- public bool IsFolderSelected { get; set; }
+ public bool IsFileSelected { get; set; }
+ public bool IsFolderSelected { get; set; } = true; // Default to Folder
private bool IsEdit { get; }
private AccessLink SelectedAccessLink { get; }
public ObservableCollection QuickAccessLinks { get; }
+ private ResultType _accessLinkType = ResultType.Folder; // Default to Folder
+
public QuickAccessLinkSettings(ObservableCollection quickAccessLinks)
{
IsEdit = false;
From b18d0a8bdbcff45ec470528f83f30e1656964772 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 17 Jun 2025 16:55:23 +0800
Subject: [PATCH 1569/1697] Improve code quality
---
.../ViewModels/ActionKeywordModel.cs | 19 +++--------
.../Views/ActionKeywordSetting.xaml.cs | 32 ++++---------------
.../Views/ExplorerSettings.xaml | 3 +-
.../Views/PreviewPanel.xaml.cs | 12 ++-----
.../Views/QuickAccessLinkSettings.xaml.cs | 12 ++-----
5 files changed, 18 insertions(+), 60 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/ActionKeywordModel.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/ActionKeywordModel.cs
index 745032d2c..2c4c4e54f 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/ActionKeywordModel.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/ActionKeywordModel.cs
@@ -1,16 +1,11 @@
-using System.ComponentModel;
-using System.Runtime.CompilerServices;
+#nullable enable
-#nullable enable
-
-namespace Flow.Launcher.Plugin.Explorer.Views
+namespace Flow.Launcher.Plugin.Explorer.ViewModels
{
- public class ActionKeywordModel : INotifyPropertyChanged
+ public partial class ActionKeywordModel : BaseModel
{
private static Settings _settings = null!;
- public event PropertyChangedEventHandler? PropertyChanged;
-
public static void Init(Settings settings)
{
_settings = settings;
@@ -28,13 +23,7 @@ namespace Flow.Launcher.Plugin.Explorer.Views
internal Settings.ActionKeyword KeywordProperty { get; }
- private void OnPropertyChanged([CallerMemberName] string propertyName = "")
- {
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
- }
-
private string? keyword;
-
public string Keyword
{
get => keyword ??= _settings.GetActionKeyword(KeywordProperty);
@@ -45,8 +34,8 @@ namespace Flow.Launcher.Plugin.Explorer.Views
OnPropertyChanged();
}
}
- private bool? enabled;
+ private bool? enabled;
public bool Enabled
{
get => enabled ??= _settings.GetActionKeywordEnabled(KeywordProperty);
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml.cs
index 10ce28fe4..829a2feed 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml.cs
@@ -1,16 +1,13 @@
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Linq;
-using System.Runtime.CompilerServices;
+using System.Linq;
using System.Windows;
using System.Windows.Input;
+using CommunityToolkit.Mvvm.ComponentModel;
+using Flow.Launcher.Plugin.Explorer.ViewModels;
namespace Flow.Launcher.Plugin.Explorer.Views
{
- ///
- /// Interaction logic for ActionKeywordSetting.xaml
- ///
- public partial class ActionKeywordSetting : INotifyPropertyChanged
+ [INotifyPropertyChanged]
+ public partial class ActionKeywordSetting
{
private ActionKeywordModel CurrentActionKeyword { get; }
@@ -21,14 +18,14 @@ namespace Flow.Launcher.Plugin.Explorer.Views
{
// Set Enable to be true if user change ActionKeyword
KeywordEnabled = true;
- _ = SetField(ref actionKeyword, value);
+ _ = SetProperty(ref actionKeyword, value);
}
}
public bool KeywordEnabled
{
get => _keywordEnabled;
- set => SetField(ref _keywordEnabled, value);
+ set => _ = SetProperty(ref _keywordEnabled, value);
}
private string actionKeyword;
@@ -116,20 +113,5 @@ namespace Flow.Launcher.Plugin.Explorer.Views
e.CancelCommand();
}
}
-
- 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))
- return false;
- field = value;
- OnPropertyChanged(propertyName);
- return true;
- }
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
index 8f4b4d862..59373b4de 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
@@ -8,7 +8,6 @@
xmlns:qa="clr-namespace:Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks"
xmlns:ui="http://schemas.modernwpf.com/2019"
xmlns:viewModels="clr-namespace:Flow.Launcher.Plugin.Explorer.ViewModels"
- xmlns:views="clr-namespace:Flow.Launcher.Plugin.Explorer.Views"
d:DataContext="{d:DesignInstance viewModels:SettingsViewModel}"
d:DesignHeight="450"
d:DesignWidth="800"
@@ -18,7 +17,7 @@
-
+
Date: Tue, 17 Jun 2025 16:58:48 +0800
Subject: [PATCH 1570/1697] Improve code quality
---
...low.Launcher.Plugin.BrowserBookmark.csproj | 35 ++-----------------
.../Views/SettingsControl.xaml.cs | 11 +++---
2 files changed, 8 insertions(+), 38 deletions(-)
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 49ae26564..1211cdf18 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj
@@ -37,41 +37,11 @@
-
+
-
+
@@ -95,6 +65,7 @@
+
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml.cs
index 3182adfed..1ee6b5c45 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml.cs
@@ -1,12 +1,13 @@
using System.Windows;
-using Flow.Launcher.Plugin.BrowserBookmark.Models;
using System.Windows.Input;
-using System.ComponentModel;
using System.Threading.Tasks;
+using CommunityToolkit.Mvvm.ComponentModel;
+using Flow.Launcher.Plugin.BrowserBookmark.Models;
namespace Flow.Launcher.Plugin.BrowserBookmark.Views;
-public partial class SettingsControl : INotifyPropertyChanged
+[INotifyPropertyChanged]
+public partial class SettingsControl
{
public Settings Settings { get; }
public CustomBrowser SelectedCustomBrowser { get; set; }
@@ -53,12 +54,10 @@ public partial class SettingsControl : INotifyPropertyChanged
set
{
Settings.OpenInNewBrowserWindow = value;
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(OpenInNewBrowserWindow)));
+ OnPropertyChanged();
}
}
- public event PropertyChangedEventHandler PropertyChanged;
-
private void NewCustomBrowser(object sender, RoutedEventArgs e)
{
var newBrowser = new CustomBrowser();
From bc8e77ae02ce8b41f6062b700426c15e81a04c05 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 17 Jun 2025 17:00:28 +0800
Subject: [PATCH 1571/1697] Fix format
---
...low.Launcher.Plugin.BrowserBookmark.csproj | 34 +++++++++++++++++--
1 file changed, 32 insertions(+), 2 deletions(-)
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 1211cdf18..3fb0fa46f 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj
@@ -37,11 +37,41 @@
-
+
-
+
From 7b726d86d3b9820eb4bbd2382e4d05bce18c1cd7 Mon Sep 17 00:00:00 2001
From: DB P
Date: Wed, 18 Jun 2025 18:23:00 +0900
Subject: [PATCH 1572/1697] Add new time format option "dd MMMM yyyy"
---
.../SettingPages/ViewModels/SettingsPaneThemeViewModel.cs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
index 79465cd71..b62a35495 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
@@ -170,7 +170,8 @@ public partial class SettingsPaneThemeViewModel : BaseModel
"dddd dd', 'MMMM",
"dd', 'MMMM",
"dd.MM.yy",
- "dd.MM.yyyy"
+ "dd.MM.yyyy",
+ "dd MMMM yyyy"
};
public string TimeFormat
From 8a54cc20ce991c46aed158e13cf5b3d537541a45 Mon Sep 17 00:00:00 2001
From: Jeremy
Date: Wed, 18 Jun 2025 21:17:04 +1000
Subject: [PATCH 1573/1697] update pre-release's release message
---
appveyor.yml | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/appveyor.yml b/appveyor.yml
index a430b28f4..646594f4a 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -69,7 +69,17 @@ deploy:
- provider: GitHub
repository: Flow-Launcher/Prereleases
release: v$(prereleaseTag)
- description: 'This is the early access build of our upcoming release. All changes contained here are reviewed, tested and stable to use.\n\nSee our [release](https://github.com/Flow-Launcher/Flow.Launcher/pulls?q=is%3Aopen+is%3Apr+label%3Arelease) Pull Request for details.\n\nFor latest production release visit [here](https://github.com/Flow-Launcher/Flow.Launcher/releases/latest)\n\nPlease report any bugs or issues over at the [main repository](https://github.com/Flow-Launcher/Flow.Launcher/issues)'
+ description: |
+ This is the early access build of our upcoming release.
+ All changes contained here are reviewed, tested and stable to use.
+
+ This build includes new changes from commit:
+ $(APPVEYOR_REPO_COMMIT_MESSAGE)
+
+ See all changes in this early access by going to the [milstones](https://github.com/Flow-Launcher/Flow.Launcher/milestones?sort=title&direction=asc) section and choosing the upcoming milestone.
+ For latest production release visit [here](https://github.com/Flow-Launcher/Flow.Launcher/releases/latest)
+
+ Please report any bugs or issues over at the [main repository](https://github.com/Flow-Launcher/Flow.Launcher/issues)'
auth_token:
secure: ij4UeXUYQBDJxn2YRAAhUOjklOGVKDB87Hn5J8tKIzj13yatoI7sLM666QDQFEgv
artifact: Squirrel Installer, Portable Version, Squirrel nupkg, Squirrel RELEASES
From 40e5c04ca1aacac34809ba1f0f95ac4f7bde76dd Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Thu, 19 Jun 2025 21:05:26 +1000
Subject: [PATCH 1574/1697] Fix false failing spell check rules (#3745)
---
.github/actions/spelling/expect.txt | 15 ++-------------
.github/actions/spelling/patterns.txt | 12 ++++++++++++
2 files changed, 14 insertions(+), 13 deletions(-)
diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt
index 6ba41e410..177c00fa2 100644
--- a/.github/actions/spelling/expect.txt
+++ b/.github/actions/spelling/expect.txt
@@ -1,3 +1,5 @@
+# This file should contain names of products, companies, or individuals that aren't in a standard dictionary (e.g., GitHub, Keptn, VSCode).
+
crowdin
DWM
workflows
@@ -34,7 +36,6 @@ mscorlib
pythonw
dotnet
winget
-jjw24
wolframalpha
gmail
duckduckgo
@@ -49,7 +50,6 @@ srchadmin
EWX
dlgtext
CMD
-appref-ms
appref
TSource
runas
@@ -57,7 +57,6 @@ dpi
popup
ptr
pluginindicator
-TobiasSekan
img
resx
bak
@@ -68,9 +67,6 @@ dlg
ddd
dddd
clearlogfolder
-ACCENT_ENABLE_TRANSPARENTGRADIENT
-ACCENT_ENABLE_BLURBEHIND
-WCA_ACCENT_POLICY
HGlobal
dopusrt
firefox
@@ -91,22 +87,15 @@ keyevent
KListener
requery
vkcode
-čeština
Polski
Srpski
-Português
-Português (Brasil)
Italiano
-Slovenský
quicklook
-Tiếng Việt
Droplex
Preinstalled
errormetadatafile
noresult
pluginsmanager
alreadyexists
-JsonRPC
-JsonRPCV2
Softpedia
img
diff --git a/.github/actions/spelling/patterns.txt b/.github/actions/spelling/patterns.txt
index f29f57ad5..5ef8859fc 100644
--- a/.github/actions/spelling/patterns.txt
+++ b/.github/actions/spelling/patterns.txt
@@ -1,4 +1,6 @@
# See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns
+# This file should contain strings that contain a mix of letters and numbers, or specific symbols
+
# Questionably acceptable forms of `in to`
# Personally, I prefer `log into`, but people object
@@ -121,3 +123,13 @@
# version suffix v#
(?:(?<=[A-Z]{2})V|(?<=[a-z]{2}|[A-Z]{2})v)\d+(?:\b|(?=[a-zA-Z_]))
+
+\bjjw24\b
+\bappref-ms\b
+\bTobiasSekan\b
+\bJsonRPC\b
+\bJsonRPCV2\b
+\bTiếng Việt\b
+\bPortuguês (Brasil)\b
+\bčeština\b
+\bPortuguês\b
From 64a3aa583f72be608e3e513aebf2c0f028e49346 Mon Sep 17 00:00:00 2001
From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Thu, 19 Jun 2025 19:29:50 +0800
Subject: [PATCH 1575/1697] Fix Off-by-one in index mapping when consecutive
Chinese chars
Found by code rabbit
---
Flow.Launcher.Infrastructure/PinyinAlphabet.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
index 37b7bb8c3..ffb92a9bf 100644
--- a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
+++ b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
@@ -107,8 +107,8 @@ namespace Flow.Launcher.Infrastructure
string translated = _settings.UseDoublePinyin ? ToDoublePin(resultList[i]) : resultList[i];
if (previousIsChinese)
{
- map.AddNewIndex(i, resultBuilder.Length, translated.Length + 1);
resultBuilder.Append(' ');
+ map.AddNewIndex(i, resultBuilder.Length, translated.Length + 1);
resultBuilder.Append(translated);
}
else
From b18959514d439bfb4571cb75dc1661e03c22a7bf Mon Sep 17 00:00:00 2001
From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Thu, 19 Jun 2025 19:35:01 +0800
Subject: [PATCH 1576/1697] Add OnPropertyChanged() for double pinyin
properties
---
.../UserSettings/Settings.cs | 28 +++++++++++++++++--
1 file changed, 26 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index e7306e3dd..ae3c4a396 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -290,9 +290,33 @@ namespace Flow.Launcher.Infrastructure.UserSettings
///
public bool ShouldUsePinyin { get; set; } = false;
- public bool UseDoublePinyin { get; set; } = true; //For developing
+ private bool _useDoublePinyin = true; // TODO: change default to false BEFORE RELEASE
+ public bool UseDoublePinyin
+ {
+ get => _useDoublePinyin;
+ set
+ {
+ if (_useDoublePinyin != value)
+ {
+ _useDoublePinyin = value;
+ OnPropertyChanged();
+ }
+ }
+ }
- public string DoublePinyinSchema { get; set; } = "XiaoHe"; //For developing
+ private string _doublePinyinSchema = "XiaoHe";
+ public string DoublePinyinSchema
+ {
+ get => _doublePinyinSchema;
+ set
+ {
+ if (_doublePinyinSchema != value)
+ {
+ _doublePinyinSchema = value;
+ OnPropertyChanged();
+ }
+ }
+ }
public bool AlwaysPreview { get; set; } = false;
From d2dc307bc020ebd8205ce01ee8ae5e262703a943 Mon Sep 17 00:00:00 2001
From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Thu, 19 Jun 2025 20:06:01 +0800
Subject: [PATCH 1577/1697] Fix logic of ShouldTranslate()
---
Flow.Launcher.Infrastructure/PinyinAlphabet.cs | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
index ffb92a9bf..91c13ffad 100644
--- a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
+++ b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
@@ -76,9 +76,7 @@ namespace Flow.Launcher.Infrastructure
public bool ShouldTranslate(string stringToTranslate)
{
- return _settings.UseDoublePinyin ?
- (!WordsHelper.HasChinese(stringToTranslate) && stringToTranslate.Length % 2 == 0) :
- !WordsHelper.HasChinese(stringToTranslate);
+ return WordsHelper.HasChinese(stringToTranslate);
}
public (string translation, TranslationMapping map) Translate(string content)
From 1bc80d5dd99cdc2fdf6ee900c1c5c4d351a0a1eb Mon Sep 17 00:00:00 2001
From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Thu, 19 Jun 2025 21:52:15 +0800
Subject: [PATCH 1578/1697] Fix translated length
---
Flow.Launcher.Infrastructure/PinyinAlphabet.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
index 91c13ffad..f11a49613 100644
--- a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
+++ b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
@@ -106,7 +106,7 @@ namespace Flow.Launcher.Infrastructure
if (previousIsChinese)
{
resultBuilder.Append(' ');
- map.AddNewIndex(i, resultBuilder.Length, translated.Length + 1);
+ map.AddNewIndex(i, resultBuilder.Length, translated.Length);
resultBuilder.Append(translated);
}
else
From 247355e1427af61d73f39fafedd66b2f0d2f6909 Mon Sep 17 00:00:00 2001
From: Jeremy
Date: Sat, 21 Jun 2025 21:34:49 +1000
Subject: [PATCH 1579/1697] simplify assignee by using filtered PR list
---
.github/update_release_pr.py | 15 ++++++---------
1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/.github/update_release_pr.py b/.github/update_release_pr.py
index ccea511b3..bf5f9a15e 100644
--- a/.github/update_release_pr.py
+++ b/.github/update_release_pr.py
@@ -107,14 +107,12 @@ def get_prs(pull_request_items: list[dict], label: str = "", state: str = "all")
return pr_list
-def get_prs_assignees(pull_request_items: list[dict], label: str = "", state: str = "all") -> list[str]:
+def get_prs_assignees(pull_request_items: list[dict]) -> list[str]:
"""
- Returns a list of pull request assignees after applying the label and state filters, excludes jjw24.
+ Returns a list of pull request assignees, excludes jjw24.
Args:
- pull_request_items (list[dict]): List of PR items.
- label (str): The label name. Filter is not applied when empty string.
- state (str): State of PR, e.g. open, closed, all
+ pull_request_items (list[dict]): List of PR items to get the assignees from.
Returns:
list: A list of strs, where each string is an assignee name. List is not distinct, so can contain
@@ -123,10 +121,9 @@ def get_prs_assignees(pull_request_items: list[dict], label: str = "", state: st
"""
assignee_list = []
for pr in pull_request_items:
- if state in [pr["state"], "all"] and (not label or [item for item in pr["labels"] if item["name"] == label]):
- [assignee_list.append(assignee["login"]) for assignee in pr["assignees"] if assignee["login"] != "jjw24" ]
+ [assignee_list.append(assignee["login"]) for assignee in pr["assignees"] if assignee["login"] != "jjw24" ]
- print(f"Found {len(assignee_list)} assignees with {label if label else 'no filter on'} label and state as {state}")
+ print(f"Found {len(assignee_list)} assignees")
return assignee_list
@@ -230,7 +227,7 @@ if __name__ == "__main__":
description_content += f"## Features\n{get_pr_descriptions(enhancement_prs)}" if enhancement_prs else ""
description_content += f"## Bug fixes\n{get_pr_descriptions(bug_fix_prs)}" if bug_fix_prs else ""
- assignees = list(set(get_prs_assignees(pull_requests, "enhancement", "closed") + get_prs_assignees(pull_requests, "bug", "closed")))
+ assignees = list(set(get_prs_assignees(enhancement_prs) + get_prs_assignees(bug_fix_prs)))
assignees.sort(key=str.lower)
description_content += f"### Authors:\n{', '.join(assignees)}"
From 4e57e3a66cebec0af365c2bc6b7e462644d5c92d Mon Sep 17 00:00:00 2001
From: Jeremy
Date: Sat, 21 Jun 2025 21:37:12 +1000
Subject: [PATCH 1580/1697] determine milestone from release PR instead of
querying milestones
---
.github/update_release_pr.py | 77 ++++++++++++++++--------------------
1 file changed, 34 insertions(+), 43 deletions(-)
diff --git a/.github/update_release_pr.py b/.github/update_release_pr.py
index bf5f9a15e..0ae83151d 100644
--- a/.github/update_release_pr.py
+++ b/.github/update_release_pr.py
@@ -1,11 +1,12 @@
from os import getenv
+from typing import Optional
import requests
def get_github_prs(token: str, owner: str, repo: str, label: str = "", state: str = "all") -> list[dict]:
"""
- Fetches pull requests from a GitHub repository that match a given milestone and label.
+ Fetches pull requests from a GitHub repository that match a given label and state.
Args:
token (str): GitHub token.
@@ -23,39 +24,10 @@ def get_github_prs(token: str, owner: str, repo: str, label: str = "", state: st
"Accept": "application/vnd.github.v3+json",
}
- milestone_id = None
- milestone_url = f"https://api.github.com/repos/{owner}/{repo}/milestones"
- params = {"state": "open"}
-
- try:
- response = requests.get(milestone_url, headers=headers, params=params)
- response.raise_for_status()
- milestones = response.json()
-
- if len(milestones) > 2:
- print("More than two milestones found, unable to determine the milestone required.")
- exit(1)
-
- # milestones.pop()
- for ms in milestones:
- if ms["title"] != "Future":
- milestone_id = ms["number"]
- print(f"Gathering PRs with milestone {ms['title']}...")
- break
-
- if not milestone_id:
- print(f"No suitable milestone found in repository '{owner}/{repo}'.")
- exit(1)
-
- except requests.exceptions.RequestException as e:
- print(f"Error fetching milestones: {e}")
- exit(1)
-
- # This endpoint allows filtering by milestone and label. A PR in GH's perspective is a type of issue.
+ # This endpoint allows filtering by label(and milestone). A PR in GH's perspective is a type of issue.
prs_url = f"https://api.github.com/repos/{owner}/{repo}/issues"
params = {
"state": state,
- "milestone": milestone_id,
"labels": label,
"per_page": 100,
}
@@ -83,7 +55,7 @@ def get_github_prs(token: str, owner: str, repo: str, label: str = "", state: st
return all_prs
-def get_prs(pull_request_items: list[dict], label: str = "", state: str = "all") -> list[dict]:
+def get_prs(pull_request_items: list[dict], label: str = "", state: str = "all", milestone_number: Optional[int] = None) -> list[dict]:
"""
Returns a list of pull requests after applying the label and state filters.
@@ -91,6 +63,7 @@ def get_prs(pull_request_items: list[dict], label: str = "", state: str = "all")
pull_request_items (list[dict]): List of PR items.
label (str): The label name. Filter is not applied when empty string.
state (str): State of PR, e.g. open, closed, all
+ milestone_number (Optional[int]): The milestone number to filter by. If None, no milestone filtering is applied.
Returns:
list: A list of dictionaries, where each dictionary represents a pull request.
@@ -99,11 +72,20 @@ def get_prs(pull_request_items: list[dict], label: str = "", state: str = "all")
pr_list = []
count = 0
for pr in pull_request_items:
- if state in [pr["state"], "all"] and (not label or [item for item in pr["labels"] if item["name"] == label]):
- pr_list.append(pr)
- count += 1
+ if state not in [pr["state"], "all"]:
+ continue
- print(f"Found {count} PRs with {label if label else 'no filter on'} label and state as {state}")
+ if label and not [item for item in pr["labels"] if item["name"] == label]:
+ continue
+
+ if milestone_number:
+ if not pr.get("milestone") or pr["milestone"]["number"] != milestone_number:
+ continue
+
+ pr_list.append(pr)
+ count += 1
+
+ print(f"Found {count} PRs with {label if label else 'no filter on'} label, state as {state}, and milestone {pr.get("milestone",{}).get("number","None")}")
return pr_list
@@ -204,15 +186,16 @@ if __name__ == "__main__":
print(f"Fetching {state} PRs for {repository_owner}/{repository_name} ...")
- pull_requests = get_github_prs(github_token, repository_owner, repository_name)
+ # First, get all PRs to find the release PR and determine the milestone
+ all_pull_requests = get_github_prs(github_token, repository_owner, repository_name)
- if not pull_requests:
- print("No matching pull requests found")
+ if not all_pull_requests:
+ print("No pull requests found")
exit(1)
- print(f"\nFound total of {len(pull_requests)} pull requests")
+ print(f"\nFound total of {len(all_pull_requests)} pull requests")
- release_pr = get_prs(pull_requests, "release", "open")
+ release_pr = get_prs(all_pull_requests, "release", "open")
if len(release_pr) != 1:
print(f"Unable to find the exact release PR. Returned result: {release_pr}")
@@ -220,8 +203,16 @@ if __name__ == "__main__":
print(f"Found release PR: {release_pr[0]['title']}")
- enhancement_prs = get_prs(pull_requests, "enhancement", "closed")
- bug_fix_prs = get_prs(pull_requests, "bug", "closed")
+ release_milestone_number = release_pr[0].get("milestone",{}).get("number",None)
+
+ if not release_milestone_number:
+ print("Release PR does not have a milestone assigned.")
+ exit(1)
+
+ print(f"Using milestone number: {release_milestone_number}")
+
+ enhancement_prs = get_prs(all_pull_requests, "enhancement", "closed", release_milestone_number)
+ bug_fix_prs = get_prs(all_pull_requests, "bug", "closed", release_milestone_number)
description_content = "# Release notes\n"
description_content += f"## Features\n{get_pr_descriptions(enhancement_prs)}" if enhancement_prs else ""
From 60d59668636db3bbef2488b0291328a78eacc655 Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Sat, 21 Jun 2025 11:46:12 +0000
Subject: [PATCH 1581/1697] formatting
---
.github/update_release_pr.py | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/.github/update_release_pr.py b/.github/update_release_pr.py
index 0ae83151d..68e4c0659 100644
--- a/.github/update_release_pr.py
+++ b/.github/update_release_pr.py
@@ -55,7 +55,9 @@ def get_github_prs(token: str, owner: str, repo: str, label: str = "", state: st
return all_prs
-def get_prs(pull_request_items: list[dict], label: str = "", state: str = "all", milestone_number: Optional[int] = None) -> list[dict]:
+def get_prs(
+ pull_request_items: list[dict], label: str = "", state: str = "all", milestone_number: Optional[int] = None
+) -> list[dict]:
"""
Returns a list of pull requests after applying the label and state filters.
@@ -85,10 +87,13 @@ def get_prs(pull_request_items: list[dict], label: str = "", state: str = "all",
pr_list.append(pr)
count += 1
- print(f"Found {count} PRs with {label if label else 'no filter on'} label, state as {state}, and milestone {pr.get("milestone",{}).get("number","None")}")
+ print(
+ f"Found {count} PRs with {label if label else 'no filter on'} label, state as {state}, and milestone {pr.get("milestone",{}).get("number","None")}"
+ )
return pr_list
+
def get_prs_assignees(pull_request_items: list[dict]) -> list[str]:
"""
Returns a list of pull request assignees, excludes jjw24.
@@ -103,12 +108,13 @@ def get_prs_assignees(pull_request_items: list[dict]) -> list[str]:
"""
assignee_list = []
for pr in pull_request_items:
- [assignee_list.append(assignee["login"]) for assignee in pr["assignees"] if assignee["login"] != "jjw24" ]
+ [assignee_list.append(assignee["login"]) for assignee in pr["assignees"] if assignee["login"] != "jjw24"]
print(f"Found {len(assignee_list)} assignees")
return assignee_list
+
def get_pr_descriptions(pull_request_items: list[dict]) -> str:
"""
Returns the concatenated string of pr title and number in the format of
@@ -203,7 +209,7 @@ if __name__ == "__main__":
print(f"Found release PR: {release_pr[0]['title']}")
- release_milestone_number = release_pr[0].get("milestone",{}).get("number",None)
+ release_milestone_number = release_pr[0].get("milestone", {}).get("number", None)
if not release_milestone_number:
print("Release PR does not have a milestone assigned.")
From 9b02e1f74e180c906a7b0f13cde1cfb3c38904de Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Sat, 21 Jun 2025 21:52:54 +1000
Subject: [PATCH 1582/1697] fix typo
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
.github/update_release_pr.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/update_release_pr.py b/.github/update_release_pr.py
index 68e4c0659..d637a3275 100644
--- a/.github/update_release_pr.py
+++ b/.github/update_release_pr.py
@@ -88,7 +88,7 @@ def get_prs(
count += 1
print(
- f"Found {count} PRs with {label if label else 'no filter on'} label, state as {state}, and milestone {pr.get("milestone",{}).get("number","None")}"
+ f"Found {count} PRs with {label if label else 'no filter on'} label, state as {state}, and milestone {pr.get('milestone', {}).get('number', 'None')}"
)
return pr_list
From d68964bfa2e0942ae3345adecf5fe507e4bdb266 Mon Sep 17 00:00:00 2001
From: TBM13
Date: Thu, 26 Jun 2025 02:58:24 -0300
Subject: [PATCH 1583/1697] Calculator: Support hex numbers
---
Plugins/Flow.Launcher.Plugin.Calculator/Main.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs
index b1e4cd606..eb3c808e7 100644
--- a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs
@@ -20,7 +20,7 @@ namespace Flow.Launcher.Plugin.Calculator
@"bin2dec|hex2dec|oct2dec|" +
@"factorial|sign|isprime|isinfty|" +
@"==|~=|&&|\|\||(?:\<|\>)=?|" +
- @"[ei]|[0-9]|[\+\%\-\*\/\^\., ""]|[\(\)\|\!\[\]]" +
+ @"[ei]|[0-9]|0x[\da-fA-F]+|[\+\%\-\*\/\^\., ""]|[\(\)\|\!\[\]]" +
@")+$", RegexOptions.Compiled);
private static readonly Regex RegBrackets = new Regex(@"[\(\)\[\]]", RegexOptions.Compiled);
private static Engine MagesEngine;
From c9de2f02f8f2466da2853404bdeb49056ac17d61 Mon Sep 17 00:00:00 2001
From: DB P
Date: Fri, 27 Jun 2025 18:51:51 +0900
Subject: [PATCH 1584/1697] Fix Card Error
---
Flow.Launcher/Resources/Controls/Card.xaml | 6 ++---
Flow.Launcher/Resources/Controls/Card.xaml.cs | 5 ++++-
.../Views/SettingsPaneGeneral.xaml | 22 ++++++++++++++-----
.../Views/SettingsPaneHotkey.xaml | 19 ++++++++++++++--
.../SettingPages/Views/SettingsPaneProxy.xaml | 10 ++++-----
.../SettingPages/Views/SettingsPaneTheme.xaml | 16 ++++++++++----
6 files changed, 58 insertions(+), 20 deletions(-)
diff --git a/Flow.Launcher/Resources/Controls/Card.xaml b/Flow.Launcher/Resources/Controls/Card.xaml
index 33c1299a9..e3c5f8194 100644
--- a/Flow.Launcher/Resources/Controls/Card.xaml
+++ b/Flow.Launcher/Resources/Controls/Card.xaml
@@ -38,21 +38,21 @@
-
+
-
+
-
+
diff --git a/Flow.Launcher/Resources/Controls/Card.xaml.cs b/Flow.Launcher/Resources/Controls/Card.xaml.cs
index c8f788aca..6a70dded2 100644
--- a/Flow.Launcher/Resources/Controls/Card.xaml.cs
+++ b/Flow.Launcher/Resources/Controls/Card.xaml.cs
@@ -9,7 +9,10 @@ namespace Flow.Launcher.Resources.Controls
{
Default,
Inside,
- InsideFit
+ InsideFit,
+ First,
+ Middle,
+ Last
}
public Card()
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
index 7f8555d65..d114736d5 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
@@ -91,7 +91,10 @@
-
+
@@ -196,7 +200,10 @@
-
+
-
+
+ Sub="{DynamicResource KoreanImeRegistryTooltip}"
+ Type="First">
+ Sub="{DynamicResource KoreanImeOpenLinkToolTip}"
+ Type="Last">
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml
index 89eb2dccd..0bf4ed8ce 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml
@@ -51,7 +51,10 @@
-
+
-
+
+
+
+
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneProxy.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneProxy.xaml
index f429a6e29..588f9228e 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneProxy.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneProxy.xaml
@@ -32,35 +32,35 @@
TextAlignment="left" />
-
+
-
+
-
+
-
+
-
+
+ Sub="{Binding BackdropSubText}"
+ Type="First">
+ Icon=""
+ Type="Last">
-
+
-
+
Date: Fri, 27 Jun 2025 18:51:51 +0900
Subject: [PATCH 1585/1697] Fix Card Error
---
Flow.Launcher/Resources/Controls/Card.xaml | 6 ++---
Flow.Launcher/Resources/Controls/Card.xaml.cs | 5 ++++-
.../Views/SettingsPaneGeneral.xaml | 22 ++++++++++++++-----
.../Views/SettingsPaneHotkey.xaml | 19 ++++++++++++++--
.../SettingPages/Views/SettingsPaneProxy.xaml | 10 ++++-----
.../SettingPages/Views/SettingsPaneTheme.xaml | 16 ++++++++++----
6 files changed, 58 insertions(+), 20 deletions(-)
diff --git a/Flow.Launcher/Resources/Controls/Card.xaml b/Flow.Launcher/Resources/Controls/Card.xaml
index 33c1299a9..e3c5f8194 100644
--- a/Flow.Launcher/Resources/Controls/Card.xaml
+++ b/Flow.Launcher/Resources/Controls/Card.xaml
@@ -38,21 +38,21 @@
-
+
-
+
-
+
diff --git a/Flow.Launcher/Resources/Controls/Card.xaml.cs b/Flow.Launcher/Resources/Controls/Card.xaml.cs
index c8f788aca..6a70dded2 100644
--- a/Flow.Launcher/Resources/Controls/Card.xaml.cs
+++ b/Flow.Launcher/Resources/Controls/Card.xaml.cs
@@ -9,7 +9,10 @@ namespace Flow.Launcher.Resources.Controls
{
Default,
Inside,
- InsideFit
+ InsideFit,
+ First,
+ Middle,
+ Last
}
public Card()
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
index 7f8555d65..d114736d5 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
@@ -91,7 +91,10 @@
-
+
@@ -196,7 +200,10 @@
-
+
-
+
+ Sub="{DynamicResource KoreanImeRegistryTooltip}"
+ Type="First">
+ Sub="{DynamicResource KoreanImeOpenLinkToolTip}"
+ Type="Last">
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml
index 89eb2dccd..0bf4ed8ce 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml
@@ -51,7 +51,10 @@
-
+
-
+
+
+
+
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneProxy.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneProxy.xaml
index f429a6e29..7d894e1b3 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneProxy.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneProxy.xaml
@@ -32,35 +32,35 @@
TextAlignment="left" />
-
+
-
+
-
+
-
+
-
+
+ Sub="{Binding BackdropSubText}"
+ Type="First">
+ Icon=""
+ Type="Last">
-
+
-
+
Date: Fri, 27 Jun 2025 19:53:09 +0900
Subject: [PATCH 1586/1697] Add Separator and margin
---
Flow.Launcher/ReleaseNotesWindow.xaml.cs | 39 ++++++++++++++++--------
1 file changed, 27 insertions(+), 12 deletions(-)
diff --git a/Flow.Launcher/ReleaseNotesWindow.xaml.cs b/Flow.Launcher/ReleaseNotesWindow.xaml.cs
index 59646f35a..9a05bb46a 100644
--- a/Flow.Launcher/ReleaseNotesWindow.xaml.cs
+++ b/Flow.Launcher/ReleaseNotesWindow.xaml.cs
@@ -189,31 +189,46 @@ namespace Flow.Launcher
var releases = JsonSerializer.Deserialize>(releaseNotesJSON);
// Get the latest releases
- var latestReleases = releases.OrderByDescending(release => release.PublishedDate).Take(3);
+ var latestReleases = releases.OrderByDescending(release => release.PublishedDate).Take(3).ToList(); // .ToList()를 추가하여 인덱스로 접근 가능하게 함
// Build the release notes in Markdown format
var releaseNotesHtmlBuilder = new StringBuilder(string.Empty);
- foreach (var release in latestReleases)
+
+ for (int i = 0; i < latestReleases.Count; i++)
{
+ var release = latestReleases[i];
releaseNotesHtmlBuilder.AppendLine("# " + release.Name);
// Because MdXaml.Html package cannot correctly render images without units,
// We need to manually add unit for images
// E.g. Replace
with
var notes = ImageUnitRegex().Replace(release.ReleaseNotes, m =>
- {
- var prefix = m.Groups[1].Value;
- var widthValue = m.Groups[2].Value;
- var quote = m.Groups[3].Value;
- var suffix = m.Groups[4].Value;
- // Only replace if width is number like 500 without units like 500px
- if (IsNumber(widthValue))
- return $"{prefix}{widthValue}px{quote}{suffix}";
- return m.Value;
- });
+ {
+ var prefix = m.Groups[1].Value;
+ var widthValue = m.Groups[2].Value;
+ var quote = m.Groups[3].Value;
+ var suffix = m.Groups[4].Value;
+ // Only replace if width is number like 500 without units like 500px
+ if (IsNumber(widthValue))
+ return $"{prefix}{widthValue}px{quote}{suffix}";
+ return m.Value;
+ });
releaseNotesHtmlBuilder.AppendLine(notes);
releaseNotesHtmlBuilder.AppendLine();
+
+ // If not last release note
+ if (i < latestReleases.Count - 1)
+ {
+ releaseNotesHtmlBuilder.Append("
");
+ releaseNotesHtmlBuilder.Append("\n\n");
+
+ releaseNotesHtmlBuilder.AppendLine("---");
+
+ releaseNotesHtmlBuilder.Append("\n\n");
+ releaseNotesHtmlBuilder.Append("
");
+ releaseNotesHtmlBuilder.Append("\n\n");
+ }
}
return releaseNotesHtmlBuilder.ToString();
From 35a38f6c33370d85cdb189c2d21f924756401eea Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 27 Jun 2025 19:16:00 +0800
Subject: [PATCH 1587/1697] Improve code comments
---
Flow.Launcher/ReleaseNotesWindow.xaml.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/ReleaseNotesWindow.xaml.cs b/Flow.Launcher/ReleaseNotesWindow.xaml.cs
index 9a05bb46a..ce7a3e084 100644
--- a/Flow.Launcher/ReleaseNotesWindow.xaml.cs
+++ b/Flow.Launcher/ReleaseNotesWindow.xaml.cs
@@ -189,7 +189,7 @@ namespace Flow.Launcher
var releases = JsonSerializer.Deserialize>(releaseNotesJSON);
// Get the latest releases
- var latestReleases = releases.OrderByDescending(release => release.PublishedDate).Take(3).ToList(); // .ToList()를 추가하여 인덱스로 접근 가능하게 함
+ var latestReleases = releases.OrderByDescending(release => release.PublishedDate).Take(3).ToList();
// Build the release notes in Markdown format
var releaseNotesHtmlBuilder = new StringBuilder(string.Empty);
@@ -217,7 +217,7 @@ namespace Flow.Launcher
releaseNotesHtmlBuilder.AppendLine(notes);
releaseNotesHtmlBuilder.AppendLine();
- // If not last release note
+ // Add separator if it is not last release note
if (i < latestReleases.Count - 1)
{
releaseNotesHtmlBuilder.Append("
");
From bafb5d7b0a97c035160c8da1c21304cf5018d509 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 27 Jun 2025 19:38:36 +0800
Subject: [PATCH 1588/1697] Removed RenameFileHotkey
---
Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml | 9 ---------
1 file changed, 9 deletions(-)
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml
index 0bf4ed8ce..d7f5772bb 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml
@@ -210,15 +210,6 @@
-
-
-
From 71e975a68c422e0887e71b1a3f9c848ae3469e18 Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Fri, 27 Jun 2025 22:58:20 +1000
Subject: [PATCH 1589/1697] Update Calculator plugin description (#3781)
---
Plugins/Flow.Launcher.Plugin.Calculator/plugin.json | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/plugin.json b/Plugins/Flow.Launcher.Plugin.Calculator/plugin.json
index 485babd26..3168edfcc 100644
--- a/Plugins/Flow.Launcher.Plugin.Calculator/plugin.json
+++ b/Plugins/Flow.Launcher.Plugin.Calculator/plugin.json
@@ -2,11 +2,11 @@
"ID": "CEA0FDFC6D3B4085823D60DC76F28855",
"ActionKeyword": "*",
"Name": "Calculator",
- "Description": "Provide mathematical calculations.(Try 5*3-2 in Flow Launcher)",
+ "Description": "Perform mathematical calculations (including hexadecimal values)",
"Author": "cxfksword",
"Version": "1.0.0",
"Language": "csharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.Calculator.dll",
"IcoPath": "Images\\calculator.png"
-}
\ No newline at end of file
+}
From 03c1e589225cf5e46234567bbf9867d9af14b029 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 28 Jun 2025 11:00:56 +0800
Subject: [PATCH 1590/1697] Support volume type for quick access link
---
Plugins/Flow.Launcher.Plugin.Explorer/Main.cs | 2 +-
.../Search/QuickAccessLinks/QuickAccess.cs | 10 ++++++----
.../Search/ResultManager.cs | 12 +++++++++++-
.../Search/SearchManager.cs | 12 ++++++++++++
4 files changed, 30 insertions(+), 6 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Main.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Main.cs
index 283820204..0d1d99f8a 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Main.cs
@@ -17,7 +17,7 @@ namespace Flow.Launcher.Plugin.Explorer
{
internal static PluginInitContext Context { get; set; }
- internal Settings Settings;
+ internal static Settings Settings { get; set; }
private SettingsViewModel viewModel;
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/QuickAccessLinks/QuickAccess.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/QuickAccessLinks/QuickAccess.cs
index 85b595390..d2fa4b9ef 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/QuickAccessLinks/QuickAccess.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/QuickAccessLinks/QuickAccess.cs
@@ -6,7 +6,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks
{
internal static class QuickAccess
{
- private const int quickAccessResultScore = 100;
+ private const int QuickAccessResultScore = 100;
internal static List AccessLinkListMatched(Query query, IEnumerable accessLinks)
{
@@ -19,8 +19,9 @@ namespace Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks
.ThenBy(x => x.Name)
.Select(l => l.Type switch
{
- ResultType.Folder => ResultManager.CreateFolderResult(l.Name, l.Path, l.Path, query, quickAccessResultScore),
- ResultType.File => ResultManager.CreateFileResult(l.Path, query, quickAccessResultScore),
+ ResultType.Volume => ResultManager.CreateDriveSpaceDisplayResult(l.Path, query.ActionKeyword, QuickAccessResultScore),
+ ResultType.Folder => ResultManager.CreateFolderResult(l.Name, l.Path, l.Path, query, QuickAccessResultScore),
+ ResultType.File => ResultManager.CreateFileResult(l.Path, query, QuickAccessResultScore),
_ => throw new ArgumentOutOfRangeException()
})
.ToList();
@@ -32,8 +33,9 @@ namespace Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks
.ThenBy(x => x.Name)
.Select(l => l.Type switch
{
+ ResultType.Volume => ResultManager.CreateDriveSpaceDisplayResult(l.Path, query.ActionKeyword, QuickAccessResultScore),
ResultType.Folder => ResultManager.CreateFolderResult(l.Name, l.Path, l.Path, query),
- ResultType.File => ResultManager.CreateFileResult(l.Path, query, quickAccessResultScore),
+ ResultType.File => ResultManager.CreateFileResult(l.Path, query, QuickAccessResultScore),
_ => throw new ArgumentOutOfRangeException()
}).ToList();
}
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
index e87d2df97..7791a9881 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
@@ -171,7 +171,17 @@ namespace Flow.Launcher.Plugin.Explorer.Search
};
}
+ internal static Result CreateDriveSpaceDisplayResult(string path, string actionKeyword, int score)
+ {
+ return CreateDriveSpaceDisplayResult(path, actionKeyword, score, SearchManager.UseIndexSearch(path));
+ }
+
internal static Result CreateDriveSpaceDisplayResult(string path, string actionKeyword, bool windowsIndexed = false)
+ {
+ return CreateDriveSpaceDisplayResult(path, actionKeyword, 500, windowsIndexed);
+ }
+
+ private static Result CreateDriveSpaceDisplayResult(string path, string actionKeyword, int score, bool windowsIndexed = false)
{
var progressBarColor = "#26a0da";
var title = string.Empty; // hide title when use progress bar,
@@ -197,7 +207,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
SubTitle = subtitle,
AutoCompleteText = GetPathWithActionKeyword(path, ResultType.Folder, actionKeyword),
IcoPath = path,
- Score = 500,
+ Score = score,
ProgressBar = progressValue,
ProgressBarColor = progressBarColor,
Preview = new Result.PreviewInfo
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
index 12df6c145..f4f87d4d4 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
@@ -246,6 +246,18 @@ namespace Flow.Launcher.Plugin.Explorer.Search
public bool IsFileContentSearch(string actionKeyword) => actionKeyword == Settings.FileContentSearchActionKeyword;
+ public static bool UseIndexSearch(string path)
+ {
+ if (Main.Settings.IndexSearchEngine is not Settings.IndexSearchEngineOption.WindowsIndex)
+ return false;
+
+ // Check if the path is using windows index search
+ var pathToDirectory = FilesFolders.ReturnPreviousDirectoryIfIncompleteString(path);
+
+ return !Main.Settings.IndexSearchExcludedSubdirectoryPaths.Any(
+ x => FilesFolders.ReturnPreviousDirectoryIfIncompleteString(pathToDirectory).StartsWith(x.Path, StringComparison.OrdinalIgnoreCase))
+ && WindowsIndex.WindowsIndex.PathIsIndexed(pathToDirectory);
+ }
private bool UseWindowsIndexForDirectorySearch(string locationPath)
{
From d6310bc4f0e129970f162ce2e54775af28d96e8a Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 28 Jun 2025 11:02:44 +0800
Subject: [PATCH 1591/1697] Add quick access result score for folder results
---
.../Search/QuickAccessLinks/QuickAccess.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/QuickAccessLinks/QuickAccess.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/QuickAccessLinks/QuickAccess.cs
index d2fa4b9ef..32651ecb8 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/QuickAccessLinks/QuickAccess.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/QuickAccessLinks/QuickAccess.cs
@@ -34,7 +34,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks
.Select(l => l.Type switch
{
ResultType.Volume => ResultManager.CreateDriveSpaceDisplayResult(l.Path, query.ActionKeyword, QuickAccessResultScore),
- ResultType.Folder => ResultManager.CreateFolderResult(l.Name, l.Path, l.Path, query),
+ ResultType.Folder => ResultManager.CreateFolderResult(l.Name, l.Path, l.Path, query, QuickAccessResultScore),
ResultType.File => ResultManager.CreateFileResult(l.Path, query, QuickAccessResultScore),
_ => throw new ArgumentOutOfRangeException()
}).ToList();
From 7c3c7680c0b8b2180ba6393300c65b5ac558a542 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 29 Jun 2025 15:47:46 +0800
Subject: [PATCH 1592/1697] Add type for card elements inside card group
---
Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
index d831774fb..ac27c3b40 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
@@ -229,7 +229,8 @@
+ Sub="{DynamicResource autoRestartAfterChangingToolTip}"
+ Type="First">
+ Sub="{DynamicResource showUnknownSourceWarningToolTip}"
+ Type="Last">
Date: Sun, 29 Jun 2025 15:48:08 +0800
Subject: [PATCH 1593/1697] Move codes to new place
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 264 ----------------
.../Helper/PluginInstallationHelper.cs | 283 ++++++++++++++++++
.../SettingsPanePluginStoreViewModel.cs | 4 +-
.../ViewModel/PluginStoreItemViewModel.cs | 7 +-
Flow.Launcher/ViewModel/PluginViewModel.cs | 3 +-
5 files changed, 291 insertions(+), 270 deletions(-)
create mode 100644 Flow.Launcher/Helper/PluginInstallationHelper.cs
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index f7a2461ab..9b525f331 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -2,12 +2,10 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
-using System.IO.Compression;
using System.Linq;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
-using System.Windows;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Core.ExternalPlugins;
using Flow.Launcher.Infrastructure;
@@ -26,8 +24,6 @@ namespace Flow.Launcher.Core.Plugin
{
private static readonly string ClassName = nameof(PluginManager);
- private static readonly Settings FlowSettings = Ioc.Default.GetRequiredService();
-
private static IEnumerable _contextMenuPlugins;
private static IEnumerable _homePlugins;
@@ -561,213 +557,6 @@ namespace Flow.Launcher.Core.Plugin
await UninstallPluginAsync(plugin, removePluginFromSettings, removePluginSettings, true);
}
- public static async Task InstallPluginAndCheckRestartAsync(UserPlugin newPlugin)
- {
- if (API.ShowMsgBox(
- string.Format(
- API.GetTranslation("InstallPromptSubtitle"),
- newPlugin.Name, newPlugin.Author, Environment.NewLine),
- API.GetTranslation("InstallPromptTitle"),
- button: MessageBoxButton.YesNo) != MessageBoxResult.Yes) return;
-
- try
- {
- // at minimum should provide a name, but handle plugin that is not downloaded from plugins manifest and is a url download
- var downloadFilename = string.IsNullOrEmpty(newPlugin.Version)
- ? $"{newPlugin.Name}-{Guid.NewGuid()}.zip"
- : $"{newPlugin.Name}-{newPlugin.Version}.zip";
-
- var filePath = Path.Combine(Path.GetTempPath(), downloadFilename);
-
- using var cts = new CancellationTokenSource();
-
- if (!newPlugin.IsFromLocalInstallPath)
- {
- await DownloadFileAsync(
- $"{API.GetTranslation("DownloadingPlugin")} {newPlugin.Name}",
- newPlugin.UrlDownload, filePath, cts);
- }
- else
- {
- filePath = newPlugin.LocalInstallPath;
- }
-
- // check if user cancelled download before installing plugin
- if (cts.IsCancellationRequested)
- {
- return;
- }
- else
- {
- if (!File.Exists(filePath))
- {
- throw new FileNotFoundException($"Plugin {newPlugin.ID} zip file not found at {filePath}", filePath);
- }
-
- API.InstallPlugin(newPlugin, filePath);
-
- if (!newPlugin.IsFromLocalInstallPath)
- {
- File.Delete(filePath);
- }
- }
- }
- catch (Exception e)
- {
- API.LogException(ClassName, "Failed to install plugin", e);
- API.ShowMsgError(API.GetTranslation("ErrorInstallingPlugin"));
- return; // don’t restart on failure
- }
-
- if (FlowSettings.AutoRestartAfterChanging)
- {
- API.RestartApp();
- }
- else
- {
- API.ShowMsg(
- API.GetTranslation("installbtn"),
- string.Format(
- API.GetTranslation(
- "InstallSuccessNoRestart"),
- newPlugin.Name));
- }
- }
-
- public static async Task InstallPluginAndCheckRestartAsync(string filePath)
- {
- UserPlugin plugin;
- try
- {
- using ZipArchive archive = ZipFile.OpenRead(filePath);
- var pluginJsonPath = archive.Entries.FirstOrDefault(x => x.Name == "plugin.json") ??
- throw new FileNotFoundException("The zip file does not contain a plugin.json file.");
- var pluginJsonEntry = archive.GetEntry(pluginJsonPath.ToString()) ??
- throw new FileNotFoundException("The zip file does not contain a plugin.json file.");
-
- using Stream stream = pluginJsonEntry.Open();
- plugin = JsonSerializer.Deserialize(stream);
- plugin.IcoPath = "Images\\zipfolder.png";
- plugin.LocalInstallPath = filePath;
- }
- catch (Exception e)
- {
- API.LogException(ClassName, "Failed to validate zip file", e);
- API.ShowMsgError(API.GetTranslation("ZipFileNotHavePluginJson"));
- return;
- }
-
- if (FlowSettings.ShowUnknownSourceWarning)
- {
- if (!InstallSourceKnown(plugin.Website)
- && API.ShowMsgBox(string.Format(
- API.GetTranslation("InstallFromUnknownSourceSubtitle"), Environment.NewLine),
- API.GetTranslation("InstallFromUnknownSourceTitle"),
- MessageBoxButton.YesNo) == MessageBoxResult.No)
- return;
- }
-
- await InstallPluginAndCheckRestartAsync(plugin);
- }
-
- public static async Task UninstallPluginAndCheckRestartAsync(PluginMetadata oldPlugin)
- {
- if (API.ShowMsgBox(
- string.Format(
- API.GetTranslation("UninstallPromptSubtitle"),
- oldPlugin.Name, oldPlugin.Author, Environment.NewLine),
- API.GetTranslation("UninstallPromptTitle"),
- button: MessageBoxButton.YesNo) != MessageBoxResult.Yes) return;
-
- var removePluginSettings = API.ShowMsgBox(
- API.GetTranslation("KeepPluginSettingsSubtitle"),
- API.GetTranslation("KeepPluginSettingsTitle"),
- button: MessageBoxButton.YesNo) == MessageBoxResult.No;
-
- try
- {
- await API.UninstallPluginAsync(oldPlugin, removePluginSettings);
- }
- catch (Exception e)
- {
- API.LogException(ClassName, "Failed to uninstall plugin", e);
- API.ShowMsgError(API.GetTranslation("ErrorUninstallingPlugin"));
- return; // don’t restart on failure
- }
-
- if (FlowSettings.AutoRestartAfterChanging)
- {
- API.RestartApp();
- }
- else
- {
- API.ShowMsg(
- API.GetTranslation("uninstallbtn"),
- string.Format(
- API.GetTranslation(
- "UninstallSuccessNoRestart"),
- oldPlugin.Name));
- }
- }
-
- public static async Task UpdatePluginAndCheckRestartAsync(UserPlugin newPlugin, PluginMetadata oldPlugin)
- {
- if (API.ShowMsgBox(
- string.Format(
- API.GetTranslation("UpdatePromptSubtitle"),
- oldPlugin.Name, oldPlugin.Author, Environment.NewLine),
- API.GetTranslation("UpdatePromptTitle"),
- button: MessageBoxButton.YesNo) != MessageBoxResult.Yes) return;
-
- try
- {
- var filePath = Path.Combine(Path.GetTempPath(), $"{newPlugin.Name}-{newPlugin.Version}.zip");
-
- using var cts = new CancellationTokenSource();
-
- if (!newPlugin.IsFromLocalInstallPath)
- {
- await DownloadFileAsync(
- $"{API.GetTranslation("DownloadingPlugin")} {newPlugin.Name}",
- newPlugin.UrlDownload, filePath, cts);
- }
- else
- {
- filePath = newPlugin.LocalInstallPath;
- }
-
- // check if user cancelled download before installing plugin
- if (cts.IsCancellationRequested)
- {
- return;
- }
- else
- {
- await API.UpdatePluginAsync(oldPlugin, newPlugin, filePath);
- }
- }
- catch (Exception e)
- {
- API.LogException(ClassName, "Failed to update plugin", e);
- API.ShowMsgError(API.GetTranslation("ErrorUpdatingPlugin"));
- return; // don’t restart on failure
- }
-
- if (FlowSettings.AutoRestartAfterChanging)
- {
- API.RestartApp();
- }
- else
- {
- API.ShowMsg(
- API.GetTranslation("updatebtn"),
- string.Format(
- API.GetTranslation(
- "UpdateSuccessNoRestart"),
- newPlugin.Name));
- }
- }
-
#endregion
#region Internal functions
@@ -915,59 +704,6 @@ namespace Flow.Launcher.Core.Plugin
}
}
- internal static async Task DownloadFileAsync(string prgBoxTitle, string downloadUrl, string filePath, CancellationTokenSource cts, bool deleteFile = true, bool showProgress = true)
- {
- if (deleteFile && File.Exists(filePath))
- File.Delete(filePath);
-
- if (showProgress)
- {
- var exceptionHappened = false;
- await 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 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 API.HttpDownloadAsync(downloadUrl, filePath, token: cts.Token).ConfigureAwait(false);
- }
- else
- {
- await API.HttpDownloadAsync(downloadUrl, filePath, token: cts.Token).ConfigureAwait(false);
- }
- }
-
- private static bool InstallSourceKnown(string url)
- {
- var pieces = url.Split('/');
-
- if (pieces.Length < 4)
- return false;
-
- var author = pieces[3];
- var acceptedSource = "https://github.com";
- var constructedUrlPart = string.Format("{0}/{1}/", acceptedSource, author);
-
- return url.StartsWith(acceptedSource) &&
- API.GetAllPlugins().Any(x =>
- !string.IsNullOrEmpty(x.Metadata.Website) &&
- x.Metadata.Website.StartsWith(constructedUrlPart)
- );
- }
-
#endregion
}
}
diff --git a/Flow.Launcher/Helper/PluginInstallationHelper.cs b/Flow.Launcher/Helper/PluginInstallationHelper.cs
new file mode 100644
index 000000000..570c5d34c
--- /dev/null
+++ b/Flow.Launcher/Helper/PluginInstallationHelper.cs
@@ -0,0 +1,283 @@
+using System;
+using System.IO;
+using System.IO.Compression;
+using System.Linq;
+using System.Text.Json;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows;
+using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.Infrastructure.UserSettings;
+using Flow.Launcher.Plugin;
+
+namespace Flow.Launcher.Helper;
+
+///
+/// Helper class for installing, updating, and uninstalling plugins.
+///
+public static class PluginInstallationHelper
+{
+ private static readonly string ClassName = nameof(PluginInstallationHelper);
+
+ private static readonly Settings Settings = Ioc.Default.GetRequiredService();
+
+ public static async Task InstallPluginAndCheckRestartAsync(UserPlugin newPlugin)
+ {
+ if (App.API.ShowMsgBox(
+ string.Format(
+ App.API.GetTranslation("InstallPromptSubtitle"),
+ newPlugin.Name, newPlugin.Author, Environment.NewLine),
+ App.API.GetTranslation("InstallPromptTitle"),
+ button: MessageBoxButton.YesNo) != MessageBoxResult.Yes) return;
+
+ try
+ {
+ // at minimum should provide a name, but handle plugin that is not downloaded from plugins manifest and is a url download
+ var downloadFilename = string.IsNullOrEmpty(newPlugin.Version)
+ ? $"{newPlugin.Name}-{Guid.NewGuid()}.zip"
+ : $"{newPlugin.Name}-{newPlugin.Version}.zip";
+
+ var filePath = Path.Combine(Path.GetTempPath(), downloadFilename);
+
+ using var cts = new CancellationTokenSource();
+
+ if (!newPlugin.IsFromLocalInstallPath)
+ {
+ await DownloadFileAsync(
+ $"{App.API.GetTranslation("DownloadingPlugin")} {newPlugin.Name}",
+ newPlugin.UrlDownload, filePath, cts);
+ }
+ else
+ {
+ filePath = newPlugin.LocalInstallPath;
+ }
+
+ // check if user cancelled download before installing plugin
+ if (cts.IsCancellationRequested)
+ {
+ return;
+ }
+ else
+ {
+ if (!File.Exists(filePath))
+ {
+ throw new FileNotFoundException($"Plugin {newPlugin.ID} zip file not found at {filePath}", filePath);
+ }
+
+ App.API.InstallPlugin(newPlugin, filePath);
+
+ if (!newPlugin.IsFromLocalInstallPath)
+ {
+ File.Delete(filePath);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ App.API.LogException(ClassName, "Failed to install plugin", e);
+ App.API.ShowMsgError(App.API.GetTranslation("ErrorInstallingPlugin"));
+ return; // don’t restart on failure
+ }
+
+ if (Settings.AutoRestartAfterChanging)
+ {
+ App.API.RestartApp();
+ }
+ else
+ {
+ App.API.ShowMsg(
+ App.API.GetTranslation("installbtn"),
+ string.Format(
+ App.API.GetTranslation(
+ "InstallSuccessNoRestart"),
+ newPlugin.Name));
+ }
+ }
+
+ public static async Task InstallPluginAndCheckRestartAsync(string filePath)
+ {
+ UserPlugin plugin;
+ try
+ {
+ using ZipArchive archive = ZipFile.OpenRead(filePath);
+ var pluginJsonPath = archive.Entries.FirstOrDefault(x => x.Name == "plugin.json") ??
+ throw new FileNotFoundException("The zip file does not contain a plugin.json file.");
+ var pluginJsonEntry = archive.GetEntry(pluginJsonPath.ToString()) ??
+ throw new FileNotFoundException("The zip file does not contain a plugin.json file.");
+
+ using Stream stream = pluginJsonEntry.Open();
+ plugin = JsonSerializer.Deserialize(stream);
+ plugin.IcoPath = "Images\\zipfolder.png";
+ plugin.LocalInstallPath = filePath;
+ }
+ catch (Exception e)
+ {
+ App.API.LogException(ClassName, "Failed to validate zip file", e);
+ App.API.ShowMsgError(App.API.GetTranslation("ZipFileNotHavePluginJson"));
+ return;
+ }
+
+ if (Settings.ShowUnknownSourceWarning)
+ {
+ if (!InstallSourceKnown(plugin.Website)
+ && App.API.ShowMsgBox(string.Format(
+ App.API.GetTranslation("InstallFromUnknownSourceSubtitle"), Environment.NewLine),
+ App.API.GetTranslation("InstallFromUnknownSourceTitle"),
+ MessageBoxButton.YesNo) == MessageBoxResult.No)
+ return;
+ }
+
+ await InstallPluginAndCheckRestartAsync(plugin);
+ }
+
+ public static async Task UninstallPluginAndCheckRestartAsync(PluginMetadata oldPlugin)
+ {
+ if (App.API.ShowMsgBox(
+ string.Format(
+ App.API.GetTranslation("UninstallPromptSubtitle"),
+ oldPlugin.Name, oldPlugin.Author, Environment.NewLine),
+ App.API.GetTranslation("UninstallPromptTitle"),
+ button: MessageBoxButton.YesNo) != MessageBoxResult.Yes) return;
+
+ var removePluginSettings = App.API.ShowMsgBox(
+ App.API.GetTranslation("KeepPluginSettingsSubtitle"),
+ App.API.GetTranslation("KeepPluginSettingsTitle"),
+ button: MessageBoxButton.YesNo) == MessageBoxResult.No;
+
+ try
+ {
+ await App.API.UninstallPluginAsync(oldPlugin, removePluginSettings);
+ }
+ catch (Exception e)
+ {
+ App.API.LogException(ClassName, "Failed to uninstall plugin", e);
+ App.API.ShowMsgError(App.API.GetTranslation("ErrorUninstallingPlugin"));
+ return; // don’t restart on failure
+ }
+
+ if (Settings.AutoRestartAfterChanging)
+ {
+ App.API.RestartApp();
+ }
+ else
+ {
+ App.API.ShowMsg(
+ App.API.GetTranslation("uninstallbtn"),
+ string.Format(
+ App.API.GetTranslation(
+ "UninstallSuccessNoRestart"),
+ oldPlugin.Name));
+ }
+ }
+
+ public static async Task UpdatePluginAndCheckRestartAsync(UserPlugin newPlugin, PluginMetadata oldPlugin)
+ {
+ if (App.API.ShowMsgBox(
+ string.Format(
+ App.API.GetTranslation("UpdatePromptSubtitle"),
+ oldPlugin.Name, oldPlugin.Author, Environment.NewLine),
+ App.API.GetTranslation("UpdatePromptTitle"),
+ button: MessageBoxButton.YesNo) != MessageBoxResult.Yes) return;
+
+ try
+ {
+ var filePath = Path.Combine(Path.GetTempPath(), $"{newPlugin.Name}-{newPlugin.Version}.zip");
+
+ using var cts = new CancellationTokenSource();
+
+ if (!newPlugin.IsFromLocalInstallPath)
+ {
+ await DownloadFileAsync(
+ $"{App.API.GetTranslation("DownloadingPlugin")} {newPlugin.Name}",
+ newPlugin.UrlDownload, filePath, cts);
+ }
+ else
+ {
+ filePath = newPlugin.LocalInstallPath;
+ }
+
+ // check if user cancelled download before installing plugin
+ if (cts.IsCancellationRequested)
+ {
+ return;
+ }
+ else
+ {
+ await App.API.UpdatePluginAsync(oldPlugin, newPlugin, filePath);
+ }
+ }
+ catch (Exception e)
+ {
+ App.API.LogException(ClassName, "Failed to update plugin", e);
+ App.API.ShowMsgError(App.API.GetTranslation("ErrorUpdatingPlugin"));
+ return; // don’t restart on failure
+ }
+
+ if (Settings.AutoRestartAfterChanging)
+ {
+ App.API.RestartApp();
+ }
+ else
+ {
+ App.API.ShowMsg(
+ App.API.GetTranslation("updatebtn"),
+ string.Format(
+ App.API.GetTranslation(
+ "UpdateSuccessNoRestart"),
+ newPlugin.Name));
+ }
+ }
+
+ private static async Task DownloadFileAsync(string prgBoxTitle, string downloadUrl, string filePath, CancellationTokenSource cts, bool deleteFile = true, bool showProgress = true)
+ {
+ if (deleteFile && File.Exists(filePath))
+ File.Delete(filePath);
+
+ if (showProgress)
+ {
+ var exceptionHappened = false;
+ await App.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 App.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 App.API.HttpDownloadAsync(downloadUrl, filePath, token: cts.Token).ConfigureAwait(false);
+ }
+ else
+ {
+ await App.API.HttpDownloadAsync(downloadUrl, filePath, token: cts.Token).ConfigureAwait(false);
+ }
+ }
+
+ private static bool InstallSourceKnown(string url)
+ {
+ var pieces = url.Split('/');
+
+ if (pieces.Length < 4)
+ return false;
+
+ var author = pieces[3];
+ var acceptedSource = "https://github.com";
+ var constructedUrlPart = string.Format("{0}/{1}/", acceptedSource, author);
+
+ return url.StartsWith(acceptedSource) &&
+ App.API.GetAllPlugins().Any(x =>
+ !string.IsNullOrEmpty(x.Metadata.Website) &&
+ x.Metadata.Website.StartsWith(constructedUrlPart)
+ );
+ }
+}
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs
index b9b7c12fa..bce7201b8 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs
@@ -4,7 +4,7 @@ using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using CommunityToolkit.Mvvm.Input;
-using Flow.Launcher.Core.Plugin;
+using Flow.Launcher.Helper;
using Flow.Launcher.Plugin;
using Flow.Launcher.ViewModel;
@@ -107,7 +107,7 @@ public partial class SettingsPanePluginStoreViewModel : BaseModel
$"{App.API.GetTranslation("ZipFiles")} (*.zip)|*.zip");
if (!string.IsNullOrEmpty(file))
- await PluginManager.InstallPluginAndCheckRestartAsync(file);
+ await PluginInstallationHelper.InstallPluginAndCheckRestartAsync(file);
}
private static string GetFileFromDialog(string title, string filter = "")
diff --git a/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs b/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs
index a504b7a05..f03d2740e 100644
--- a/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs
@@ -2,6 +2,7 @@
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.Core.Plugin;
+using Flow.Launcher.Helper;
using Flow.Launcher.Plugin;
using Version = SemanticVersioning.Version;
@@ -65,13 +66,13 @@ namespace Flow.Launcher.ViewModel
switch (action)
{
case "install":
- await PluginManager.InstallPluginAndCheckRestartAsync(_newPlugin);
+ await PluginInstallationHelper.InstallPluginAndCheckRestartAsync(_newPlugin);
break;
case "uninstall":
- await PluginManager.UninstallPluginAndCheckRestartAsync(_oldPluginPair.Metadata);
+ await PluginInstallationHelper.UninstallPluginAndCheckRestartAsync(_oldPluginPair.Metadata);
break;
case "update":
- await PluginManager.UpdatePluginAndCheckRestartAsync(_newPlugin, _oldPluginPair.Metadata);
+ await PluginInstallationHelper.UpdatePluginAndCheckRestartAsync(_newPlugin, _oldPluginPair.Metadata);
break;
default:
break;
diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs
index f902fb037..131972e85 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -5,6 +5,7 @@ using System.Windows.Media;
using CommunityToolkit.Mvvm.DependencyInjection;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.Core.Plugin;
+using Flow.Launcher.Helper;
using Flow.Launcher.Infrastructure.Image;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
@@ -172,7 +173,7 @@ namespace Flow.Launcher.ViewModel
[RelayCommand]
private async Task OpenDeletePluginWindowAsync()
{
- await PluginManager.UninstallPluginAndCheckRestartAsync(PluginPair.Metadata);
+ await PluginInstallationHelper.UninstallPluginAndCheckRestartAsync(PluginPair.Metadata);
}
[RelayCommand]
From 135fd03f88d78e85f2b3471396c58be0c8740de1 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 29 Jun 2025 15:58:52 +0800
Subject: [PATCH 1594/1697] Improve code quality
---
.../Helper/PluginInstallationHelper.cs | 24 ++++++++-----------
1 file changed, 10 insertions(+), 14 deletions(-)
diff --git a/Flow.Launcher/Helper/PluginInstallationHelper.cs b/Flow.Launcher/Helper/PluginInstallationHelper.cs
index 570c5d34c..d7ce2934c 100644
--- a/Flow.Launcher/Helper/PluginInstallationHelper.cs
+++ b/Flow.Launcher/Helper/PluginInstallationHelper.cs
@@ -57,19 +57,17 @@ public static class PluginInstallationHelper
{
return;
}
- else
+
+ if (!File.Exists(filePath))
{
- if (!File.Exists(filePath))
- {
- throw new FileNotFoundException($"Plugin {newPlugin.ID} zip file not found at {filePath}", filePath);
- }
+ throw new FileNotFoundException($"Plugin {newPlugin.ID} zip file not found at {filePath}", filePath);
+ }
- App.API.InstallPlugin(newPlugin, filePath);
+ App.API.InstallPlugin(newPlugin, filePath);
- if (!newPlugin.IsFromLocalInstallPath)
- {
- File.Delete(filePath);
- }
+ if (!newPlugin.IsFromLocalInstallPath)
+ {
+ File.Delete(filePath);
}
}
catch (Exception e)
@@ -201,10 +199,8 @@ public static class PluginInstallationHelper
{
return;
}
- else
- {
- await App.API.UpdatePluginAsync(oldPlugin, newPlugin, filePath);
- }
+
+ await App.API.UpdatePluginAsync(oldPlugin, newPlugin, filePath);
}
catch (Exception e)
{
From c5dd19ef300acc396c2a0d037ebb52f5aa288864 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 29 Jun 2025 16:03:19 +0800
Subject: [PATCH 1595/1697] Use Microsoft.Win32.OpenFileDialog instead
---
.../ViewModels/SettingsPanePluginStoreViewModel.cs | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs
index bce7201b8..2b12ba70f 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs
@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
-using System.Windows.Forms;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.Helper;
using Flow.Launcher.Plugin;
@@ -112,7 +111,7 @@ public partial class SettingsPanePluginStoreViewModel : BaseModel
private static string GetFileFromDialog(string title, string filter = "")
{
- var dlg = new OpenFileDialog
+ var dlg = new Microsoft.Win32.OpenFileDialog
{
InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "\\Downloads",
Multiselect = false,
@@ -121,12 +120,11 @@ public partial class SettingsPanePluginStoreViewModel : BaseModel
Title = title,
Filter = filter
};
+ var result = dlg.ShowDialog();
+ if (result == true)
+ return dlg.FileName;
- return dlg.ShowDialog() switch
- {
- DialogResult.OK => dlg.FileName,
- _ => string.Empty
- };
+ return string.Empty;
}
public bool SatisfiesFilter(PluginStoreItemViewModel plugin)
From 104b4b26805196bfb6c43327dac9bdf05b0d0266 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 29 Jun 2025 16:09:06 +0800
Subject: [PATCH 1596/1697] Improve code quality
---
Flow.Launcher/Helper/PluginInstallationHelper.cs | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/Flow.Launcher/Helper/PluginInstallationHelper.cs b/Flow.Launcher/Helper/PluginInstallationHelper.cs
index d7ce2934c..0d3d2df67 100644
--- a/Flow.Launcher/Helper/PluginInstallationHelper.cs
+++ b/Flow.Launcher/Helper/PluginInstallationHelper.cs
@@ -98,9 +98,7 @@ public static class PluginInstallationHelper
try
{
using ZipArchive archive = ZipFile.OpenRead(filePath);
- var pluginJsonPath = archive.Entries.FirstOrDefault(x => x.Name == "plugin.json") ??
- throw new FileNotFoundException("The zip file does not contain a plugin.json file.");
- var pluginJsonEntry = archive.GetEntry(pluginJsonPath.ToString()) ??
+ var pluginJsonEntry = archive.Entries.FirstOrDefault(x => x.Name == "plugin.json") ??
throw new FileNotFoundException("The zip file does not contain a plugin.json file.");
using Stream stream = pluginJsonEntry.Open();
From 3e9e91d71c8b0f9d63a9c7b97acb89aa6cd4d394 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 29 Jun 2025 16:24:21 +0800
Subject: [PATCH 1597/1697] Fix possible exception when extracting zip file
---
.../Languages/en.xaml | 3 +++
.../PluginsManager.cs | 26 +++++++++++++++++++
.../Utilities.cs | 4 +--
3 files changed, 30 insertions(+), 3 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml
index 573ca9051..bb0d6e5fb 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml
@@ -46,6 +46,9 @@
{0} plugins successfully updated. Please restart Flow.
Plugin {0} has already been modified. Please restart Flow before making any further changes.
+ Invalid zip installer file
+ Please check if there is plugin.json in {0}
+
Plugins Manager
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 25182f6d3..6ccd781c3 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -242,6 +242,18 @@ namespace Flow.Launcher.Plugin.PluginsManager
if (FilesFolders.IsZipFilePath(search, checkFileExists: true))
{
pluginFromLocalPath = Utilities.GetPluginInfoFromZip(search);
+
+ if (pluginFromLocalPath == null) return new List
+ {
+ new()
+ {
+ Title = Context.API.GetTranslation("plugin_pluginsmanager_invalid_zip_title"),
+ SubTitle = string.Format(Context.API.GetTranslation("plugin_pluginsmanager_invalid_zip_subtitle"),
+ search),
+ IcoPath = icoPath
+ }
+ };
+
pluginFromLocalPath.LocalInstallPath = search;
updateFromLocalPath = true;
}
@@ -559,6 +571,20 @@ namespace Flow.Launcher.Plugin.PluginsManager
{
var plugin = Utilities.GetPluginInfoFromZip(localPath);
+ if (plugin == null)
+ {
+ return new List
+ {
+ new()
+ {
+ Title = Context.API.GetTranslation("plugin_pluginsmanager_invalid_zip_title"),
+ SubTitle = string.Format(Context.API.GetTranslation("plugin_pluginsmanager_invalid_zip_subtitle"),
+ localPath),
+ IcoPath = icoPath
+ }
+ };
+ }
+
plugin.LocalInstallPath = localPath;
return new List
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Utilities.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/Utilities.cs
index 4bb78f6ff..d76ce40c4 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Utilities.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Utilities.cs
@@ -65,9 +65,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
using (ZipArchive archive = System.IO.Compression.ZipFile.OpenRead(filePath))
{
- var pluginJsonPath = archive.Entries.FirstOrDefault(x => x.Name == "plugin.json").ToString();
- ZipArchiveEntry pluginJsonEntry = archive.GetEntry(pluginJsonPath);
-
+ var pluginJsonEntry = archive.Entries.FirstOrDefault(x => x.Name == "plugin.json");
if (pluginJsonEntry != null)
{
using Stream stream = pluginJsonEntry.Open();
From a3a0c59fa3e2c3372a7c08f51d522a4a6e49149e Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 29 Jun 2025 16:29:45 +0800
Subject: [PATCH 1598/1697] Check url nullability
---
Flow.Launcher/Helper/PluginInstallationHelper.cs | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Flow.Launcher/Helper/PluginInstallationHelper.cs b/Flow.Launcher/Helper/PluginInstallationHelper.cs
index 0d3d2df67..0e94566b8 100644
--- a/Flow.Launcher/Helper/PluginInstallationHelper.cs
+++ b/Flow.Launcher/Helper/PluginInstallationHelper.cs
@@ -259,6 +259,9 @@ public static class PluginInstallationHelper
private static bool InstallSourceKnown(string url)
{
+ if (string.IsNullOrEmpty(url))
+ return false;
+
var pieces = url.Split('/');
if (pieces.Length < 4)
From bdb3616977529f256d312486b23c54687603a3f7 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 29 Jun 2025 16:34:18 +0800
Subject: [PATCH 1599/1697] Improve string resource
---
Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml
index bb0d6e5fb..742d5d8b9 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml
@@ -47,7 +47,7 @@
Plugin {0} has already been modified. Please restart Flow before making any further changes.
Invalid zip installer file
- Please check if there is plugin.json in {0}
+ Please check if there is a plugin.json in {0}
Plugins Manager
From 8e6a410cfcd6ebe56b893797bc4ba646e73c8ba7 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 29 Jun 2025 17:06:29 +0800
Subject: [PATCH 1600/1697] Use url host
---
Flow.Launcher/Helper/PluginInstallationHelper.cs | 13 ++++++++-----
.../PluginsManager.cs | 13 ++++++++-----
2 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/Flow.Launcher/Helper/PluginInstallationHelper.cs b/Flow.Launcher/Helper/PluginInstallationHelper.cs
index 0e94566b8..ea5f07bda 100644
--- a/Flow.Launcher/Helper/PluginInstallationHelper.cs
+++ b/Flow.Launcher/Helper/PluginInstallationHelper.cs
@@ -268,13 +268,16 @@ public static class PluginInstallationHelper
return false;
var author = pieces[3];
+ var acceptedHost = "github.com";
var acceptedSource = "https://github.com";
var constructedUrlPart = string.Format("{0}/{1}/", acceptedSource, author);
- return url.StartsWith(acceptedSource) &&
- App.API.GetAllPlugins().Any(x =>
- !string.IsNullOrEmpty(x.Metadata.Website) &&
- x.Metadata.Website.StartsWith(constructedUrlPart)
- );
+ if (!Uri.TryCreate(url, UriKind.Absolute, out var uri) || uri.Host != acceptedHost)
+ return false;
+
+ return App.API.GetAllPlugins().Any(x =>
+ !string.IsNullOrEmpty(x.Metadata.Website) &&
+ x.Metadata.Website.StartsWith(constructedUrlPart)
+ );
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index 6ccd781c3..c7c3ff3a2 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -626,14 +626,17 @@ namespace Flow.Launcher.Plugin.PluginsManager
return false;
var author = pieces[3];
+ var acceptedHost = "github.com";
var acceptedSource = "https://github.com";
var constructedUrlPart = string.Format("{0}/{1}/", acceptedSource, author);
- return url.StartsWith(acceptedSource) &&
- Context.API.GetAllPlugins().Any(x =>
- !string.IsNullOrEmpty(x.Metadata.Website) &&
- x.Metadata.Website.StartsWith(constructedUrlPart)
- );
+ if (!Uri.TryCreate(url, UriKind.Absolute, out var uri) || uri.Host != acceptedHost)
+ return false;
+
+ return Context.API.GetAllPlugins().Any(x =>
+ !string.IsNullOrEmpty(x.Metadata.Website) &&
+ x.Metadata.Website.StartsWith(constructedUrlPart)
+ );
}
internal async ValueTask> RequestInstallOrUpdateAsync(string search, CancellationToken token,
From 19cb3eaf6a52f651986301b06de0246ed6e9ee90 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 29 Jun 2025 18:20:47 +0800
Subject: [PATCH 1601/1697] Fix typos
---
Flow.Launcher/Helper/PluginInstallationHelper.cs | 2 +-
Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/Helper/PluginInstallationHelper.cs b/Flow.Launcher/Helper/PluginInstallationHelper.cs
index ea5f07bda..ea8195e57 100644
--- a/Flow.Launcher/Helper/PluginInstallationHelper.cs
+++ b/Flow.Launcher/Helper/PluginInstallationHelper.cs
@@ -235,7 +235,7 @@ public static class PluginInstallationHelper
{
if (reportProgress == null)
{
- // when reportProgress is null, it means there is expcetion with the progress box
+ // when reportProgress is null, it means there is exception with the progress box
// so we record it with exceptionHappened and return so that progress box will close instantly
exceptionHappened = true;
return;
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index c7c3ff3a2..c1d3a81a2 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -209,7 +209,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
{
if (reportProgress == null)
{
- // when reportProgress is null, it means there is expcetion with the progress box
+ // when reportProgress is null, it means there is exception with the progress box
// so we record it with exceptionHappened and return so that progress box will close instantly
exceptionHappened = true;
return;
From 9e868e7e3fec02ac340b79cc1f9d505d33616176 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 29 Jun 2025 22:35:14 +0800
Subject: [PATCH 1602/1697] Move plugin installer location
---
.../Plugin/PluginInstaller.cs | 100 +++++++++---------
.../SettingsPanePluginStoreViewModel.cs | 4 +-
.../ViewModel/PluginStoreItemViewModel.cs | 6 +-
Flow.Launcher/ViewModel/PluginViewModel.cs | 3 +-
.../ViewModel/SelectBrowserViewModel.cs | 1 -
5 files changed, 58 insertions(+), 56 deletions(-)
rename Flow.Launcher/Helper/PluginInstallationHelper.cs => Flow.Launcher.Core/Plugin/PluginInstaller.cs (71%)
diff --git a/Flow.Launcher/Helper/PluginInstallationHelper.cs b/Flow.Launcher.Core/Plugin/PluginInstaller.cs
similarity index 71%
rename from Flow.Launcher/Helper/PluginInstallationHelper.cs
rename to Flow.Launcher.Core/Plugin/PluginInstaller.cs
index ea8195e57..a69ab322e 100644
--- a/Flow.Launcher/Helper/PluginInstallationHelper.cs
+++ b/Flow.Launcher.Core/Plugin/PluginInstaller.cs
@@ -10,24 +10,28 @@ using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
-namespace Flow.Launcher.Helper;
+namespace Flow.Launcher.Core.Plugin;
///
/// Helper class for installing, updating, and uninstalling plugins.
///
-public static class PluginInstallationHelper
+public static class PluginInstaller
{
- private static readonly string ClassName = nameof(PluginInstallationHelper);
+ private static readonly string ClassName = nameof(PluginInstaller);
private static readonly Settings Settings = 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();
+
public static async Task InstallPluginAndCheckRestartAsync(UserPlugin newPlugin)
{
- if (App.API.ShowMsgBox(
+ if (API.ShowMsgBox(
string.Format(
- App.API.GetTranslation("InstallPromptSubtitle"),
+ API.GetTranslation("InstallPromptSubtitle"),
newPlugin.Name, newPlugin.Author, Environment.NewLine),
- App.API.GetTranslation("InstallPromptTitle"),
+ API.GetTranslation("InstallPromptTitle"),
button: MessageBoxButton.YesNo) != MessageBoxResult.Yes) return;
try
@@ -44,7 +48,7 @@ public static class PluginInstallationHelper
if (!newPlugin.IsFromLocalInstallPath)
{
await DownloadFileAsync(
- $"{App.API.GetTranslation("DownloadingPlugin")} {newPlugin.Name}",
+ $"{API.GetTranslation("DownloadingPlugin")} {newPlugin.Name}",
newPlugin.UrlDownload, filePath, cts);
}
else
@@ -63,7 +67,7 @@ public static class PluginInstallationHelper
throw new FileNotFoundException($"Plugin {newPlugin.ID} zip file not found at {filePath}", filePath);
}
- App.API.InstallPlugin(newPlugin, filePath);
+ API.InstallPlugin(newPlugin, filePath);
if (!newPlugin.IsFromLocalInstallPath)
{
@@ -72,21 +76,21 @@ public static class PluginInstallationHelper
}
catch (Exception e)
{
- App.API.LogException(ClassName, "Failed to install plugin", e);
- App.API.ShowMsgError(App.API.GetTranslation("ErrorInstallingPlugin"));
+ API.LogException(ClassName, "Failed to install plugin", e);
+ API.ShowMsgError(API.GetTranslation("ErrorInstallingPlugin"));
return; // don’t restart on failure
}
if (Settings.AutoRestartAfterChanging)
{
- App.API.RestartApp();
+ API.RestartApp();
}
else
{
- App.API.ShowMsg(
- App.API.GetTranslation("installbtn"),
+ API.ShowMsg(
+ API.GetTranslation("installbtn"),
string.Format(
- App.API.GetTranslation(
+ API.GetTranslation(
"InstallSuccessNoRestart"),
newPlugin.Name));
}
@@ -108,17 +112,17 @@ public static class PluginInstallationHelper
}
catch (Exception e)
{
- App.API.LogException(ClassName, "Failed to validate zip file", e);
- App.API.ShowMsgError(App.API.GetTranslation("ZipFileNotHavePluginJson"));
+ API.LogException(ClassName, "Failed to validate zip file", e);
+ API.ShowMsgError(API.GetTranslation("ZipFileNotHavePluginJson"));
return;
}
if (Settings.ShowUnknownSourceWarning)
{
if (!InstallSourceKnown(plugin.Website)
- && App.API.ShowMsgBox(string.Format(
- App.API.GetTranslation("InstallFromUnknownSourceSubtitle"), Environment.NewLine),
- App.API.GetTranslation("InstallFromUnknownSourceTitle"),
+ && API.ShowMsgBox(string.Format(
+ API.GetTranslation("InstallFromUnknownSourceSubtitle"), Environment.NewLine),
+ API.GetTranslation("InstallFromUnknownSourceTitle"),
MessageBoxButton.YesNo) == MessageBoxResult.No)
return;
}
@@ -128,39 +132,39 @@ public static class PluginInstallationHelper
public static async Task UninstallPluginAndCheckRestartAsync(PluginMetadata oldPlugin)
{
- if (App.API.ShowMsgBox(
+ if (API.ShowMsgBox(
string.Format(
- App.API.GetTranslation("UninstallPromptSubtitle"),
+ API.GetTranslation("UninstallPromptSubtitle"),
oldPlugin.Name, oldPlugin.Author, Environment.NewLine),
- App.API.GetTranslation("UninstallPromptTitle"),
+ API.GetTranslation("UninstallPromptTitle"),
button: MessageBoxButton.YesNo) != MessageBoxResult.Yes) return;
- var removePluginSettings = App.API.ShowMsgBox(
- App.API.GetTranslation("KeepPluginSettingsSubtitle"),
- App.API.GetTranslation("KeepPluginSettingsTitle"),
+ var removePluginSettings = API.ShowMsgBox(
+ API.GetTranslation("KeepPluginSettingsSubtitle"),
+ API.GetTranslation("KeepPluginSettingsTitle"),
button: MessageBoxButton.YesNo) == MessageBoxResult.No;
try
{
- await App.API.UninstallPluginAsync(oldPlugin, removePluginSettings);
+ await API.UninstallPluginAsync(oldPlugin, removePluginSettings);
}
catch (Exception e)
{
- App.API.LogException(ClassName, "Failed to uninstall plugin", e);
- App.API.ShowMsgError(App.API.GetTranslation("ErrorUninstallingPlugin"));
+ API.LogException(ClassName, "Failed to uninstall plugin", e);
+ API.ShowMsgError(API.GetTranslation("ErrorUninstallingPlugin"));
return; // don’t restart on failure
}
if (Settings.AutoRestartAfterChanging)
{
- App.API.RestartApp();
+ API.RestartApp();
}
else
{
- App.API.ShowMsg(
- App.API.GetTranslation("uninstallbtn"),
+ API.ShowMsg(
+ API.GetTranslation("uninstallbtn"),
string.Format(
- App.API.GetTranslation(
+ API.GetTranslation(
"UninstallSuccessNoRestart"),
oldPlugin.Name));
}
@@ -168,11 +172,11 @@ public static class PluginInstallationHelper
public static async Task UpdatePluginAndCheckRestartAsync(UserPlugin newPlugin, PluginMetadata oldPlugin)
{
- if (App.API.ShowMsgBox(
+ if (API.ShowMsgBox(
string.Format(
- App.API.GetTranslation("UpdatePromptSubtitle"),
+ API.GetTranslation("UpdatePromptSubtitle"),
oldPlugin.Name, oldPlugin.Author, Environment.NewLine),
- App.API.GetTranslation("UpdatePromptTitle"),
+ API.GetTranslation("UpdatePromptTitle"),
button: MessageBoxButton.YesNo) != MessageBoxResult.Yes) return;
try
@@ -184,7 +188,7 @@ public static class PluginInstallationHelper
if (!newPlugin.IsFromLocalInstallPath)
{
await DownloadFileAsync(
- $"{App.API.GetTranslation("DownloadingPlugin")} {newPlugin.Name}",
+ $"{API.GetTranslation("DownloadingPlugin")} {newPlugin.Name}",
newPlugin.UrlDownload, filePath, cts);
}
else
@@ -198,25 +202,25 @@ public static class PluginInstallationHelper
return;
}
- await App.API.UpdatePluginAsync(oldPlugin, newPlugin, filePath);
+ await API.UpdatePluginAsync(oldPlugin, newPlugin, filePath);
}
catch (Exception e)
{
- App.API.LogException(ClassName, "Failed to update plugin", e);
- App.API.ShowMsgError(App.API.GetTranslation("ErrorUpdatingPlugin"));
+ API.LogException(ClassName, "Failed to update plugin", e);
+ API.ShowMsgError(API.GetTranslation("ErrorUpdatingPlugin"));
return; // don’t restart on failure
}
if (Settings.AutoRestartAfterChanging)
{
- App.API.RestartApp();
+ API.RestartApp();
}
else
{
- App.API.ShowMsg(
- App.API.GetTranslation("updatebtn"),
+ API.ShowMsg(
+ API.GetTranslation("updatebtn"),
string.Format(
- App.API.GetTranslation(
+ API.GetTranslation(
"UpdateSuccessNoRestart"),
newPlugin.Name));
}
@@ -230,7 +234,7 @@ public static class PluginInstallationHelper
if (showProgress)
{
var exceptionHappened = false;
- await App.API.ShowProgressBoxAsync(prgBoxTitle,
+ await API.ShowProgressBoxAsync(prgBoxTitle,
async (reportProgress) =>
{
if (reportProgress == null)
@@ -242,18 +246,18 @@ public static class PluginInstallationHelper
}
else
{
- await App.API.HttpDownloadAsync(downloadUrl, filePath, reportProgress, cts.Token).ConfigureAwait(false);
+ await 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 App.API.HttpDownloadAsync(downloadUrl, filePath, token: cts.Token).ConfigureAwait(false);
+ await API.HttpDownloadAsync(downloadUrl, filePath, token: cts.Token).ConfigureAwait(false);
}
else
{
- await App.API.HttpDownloadAsync(downloadUrl, filePath, token: cts.Token).ConfigureAwait(false);
+ await API.HttpDownloadAsync(downloadUrl, filePath, token: cts.Token).ConfigureAwait(false);
}
}
@@ -275,7 +279,7 @@ public static class PluginInstallationHelper
if (!Uri.TryCreate(url, UriKind.Absolute, out var uri) || uri.Host != acceptedHost)
return false;
- return App.API.GetAllPlugins().Any(x =>
+ return API.GetAllPlugins().Any(x =>
!string.IsNullOrEmpty(x.Metadata.Website) &&
x.Metadata.Website.StartsWith(constructedUrlPart)
);
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs
index 2b12ba70f..efe67d016 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs
@@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.Input;
-using Flow.Launcher.Helper;
+using Flow.Launcher.Core.Plugin;
using Flow.Launcher.Plugin;
using Flow.Launcher.ViewModel;
@@ -106,7 +106,7 @@ public partial class SettingsPanePluginStoreViewModel : BaseModel
$"{App.API.GetTranslation("ZipFiles")} (*.zip)|*.zip");
if (!string.IsNullOrEmpty(file))
- await PluginInstallationHelper.InstallPluginAndCheckRestartAsync(file);
+ await PluginInstaller.InstallPluginAndCheckRestartAsync(file);
}
private static string GetFileFromDialog(string title, string filter = "")
diff --git a/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs b/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs
index f03d2740e..a985ca7ff 100644
--- a/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs
@@ -66,13 +66,13 @@ namespace Flow.Launcher.ViewModel
switch (action)
{
case "install":
- await PluginInstallationHelper.InstallPluginAndCheckRestartAsync(_newPlugin);
+ await PluginInstaller.InstallPluginAndCheckRestartAsync(_newPlugin);
break;
case "uninstall":
- await PluginInstallationHelper.UninstallPluginAndCheckRestartAsync(_oldPluginPair.Metadata);
+ await PluginInstaller.UninstallPluginAndCheckRestartAsync(_oldPluginPair.Metadata);
break;
case "update":
- await PluginInstallationHelper.UpdatePluginAndCheckRestartAsync(_newPlugin, _oldPluginPair.Metadata);
+ await PluginInstaller.UpdatePluginAndCheckRestartAsync(_newPlugin, _oldPluginPair.Metadata);
break;
default:
break;
diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs
index 131972e85..ea222d023 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -5,7 +5,6 @@ using System.Windows.Media;
using CommunityToolkit.Mvvm.DependencyInjection;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.Core.Plugin;
-using Flow.Launcher.Helper;
using Flow.Launcher.Infrastructure.Image;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
@@ -173,7 +172,7 @@ namespace Flow.Launcher.ViewModel
[RelayCommand]
private async Task OpenDeletePluginWindowAsync()
{
- await PluginInstallationHelper.UninstallPluginAndCheckRestartAsync(PluginPair.Metadata);
+ await PluginInstaller.UninstallPluginAndCheckRestartAsync(PluginPair.Metadata);
}
[RelayCommand]
diff --git a/Flow.Launcher/ViewModel/SelectBrowserViewModel.cs b/Flow.Launcher/ViewModel/SelectBrowserViewModel.cs
index 1eee6dba5..67bbbd930 100644
--- a/Flow.Launcher/ViewModel/SelectBrowserViewModel.cs
+++ b/Flow.Launcher/ViewModel/SelectBrowserViewModel.cs
@@ -1,6 +1,5 @@
using System.Collections.ObjectModel;
using System.Linq;
-using System.Windows;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
From 0290675e1100fa2eab509cd4e2227efe68172e30 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 30 Jun 2025 12:12:47 +0800
Subject: [PATCH 1603/1697] Fix explorer plugin preview margin
---
.../Views/PreviewPanel.xaml | 143 +++++++++---------
1 file changed, 69 insertions(+), 74 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml
index e200a187f..284ad32ad 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml
@@ -8,10 +8,7 @@
d:DesignHeight="300"
d:DesignWidth="300"
mc:Ignorable="d">
-
+
@@ -90,78 +87,76 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
+
+
+
From dafb0caac4a4a7745e26c5e49e1a94933e1089c0 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 30 Jun 2025 12:42:09 +0800
Subject: [PATCH 1604/1697] Remove unused using
---
Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs | 1 -
1 file changed, 1 deletion(-)
diff --git a/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs b/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs
index a985ca7ff..f5523212e 100644
--- a/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs
@@ -2,7 +2,6 @@
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.Core.Plugin;
-using Flow.Launcher.Helper;
using Flow.Launcher.Plugin;
using Version = SemanticVersioning.Version;
From ea25a661eec75486ce7b8ad3dad41addac97b2fe Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 30 Jun 2025 12:46:41 +0800
Subject: [PATCH 1605/1697] Fix an issue that after uninstalling pm, store no
longer fetches plugin until clicking on refresh.
---
Flow.Launcher/App.xaml.cs | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 5df1f88ae..6d1499f2d 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -208,6 +208,9 @@ namespace Flow.Launcher
Http.Proxy = _settings.Proxy;
+ // Initialize plugin manifest before initializing plugins so that they can use the manifest instantly
+ await API.UpdatePluginManifestAsync();
+
await PluginManager.InitializePluginsAsync();
// Change language after all plugins are initialized because we need to update plugin title based on their api
From 5b8b84a34c97b2503732311e3fd9b00a5b89b2a0 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 30 Jun 2025 12:58:44 +0800
Subject: [PATCH 1606/1697] Fix code comments
---
Flow.Launcher.Core/Plugin/PluginInstaller.cs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginInstaller.cs b/Flow.Launcher.Core/Plugin/PluginInstaller.cs
index a69ab322e..781ad3ff0 100644
--- a/Flow.Launcher.Core/Plugin/PluginInstaller.cs
+++ b/Flow.Launcher.Core/Plugin/PluginInstaller.cs
@@ -78,7 +78,7 @@ public static class PluginInstaller
{
API.LogException(ClassName, "Failed to install plugin", e);
API.ShowMsgError(API.GetTranslation("ErrorInstallingPlugin"));
- return; // don’t restart on failure
+ return; // do not restart on failure
}
if (Settings.AutoRestartAfterChanging)
@@ -152,7 +152,7 @@ public static class PluginInstaller
{
API.LogException(ClassName, "Failed to uninstall plugin", e);
API.ShowMsgError(API.GetTranslation("ErrorUninstallingPlugin"));
- return; // don’t restart on failure
+ return; // don not restart on failure
}
if (Settings.AutoRestartAfterChanging)
@@ -208,7 +208,7 @@ public static class PluginInstaller
{
API.LogException(ClassName, "Failed to update plugin", e);
API.ShowMsgError(API.GetTranslation("ErrorUpdatingPlugin"));
- return; // don’t restart on failure
+ return; // do not restart on failure
}
if (Settings.AutoRestartAfterChanging)
From 01e749ac88e2aa4f9bc5e5bcc8ee5920ec68e9ee Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 30 Jun 2025 13:07:19 +0800
Subject: [PATCH 1607/1697] Fix an issue that store install/uninstall same
plugin without restart shows error message error, should say already
installed/uninstalled
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 24 +++++++++++++++-------
Flow.Launcher/Languages/en.xaml | 5 +++++
2 files changed, 22 insertions(+), 7 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 9b525f331..5b74d80f0 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -542,7 +542,8 @@ namespace Flow.Launcher.Core.Plugin
public static async Task UpdatePluginAsync(PluginMetadata existingVersion, UserPlugin newVersion, string zipFilePath)
{
- InstallPlugin(newVersion, zipFilePath, checkModified:false);
+ var success = InstallPlugin(newVersion, zipFilePath, checkModified:false);
+ if (!success) return;
await UninstallPluginAsync(existingVersion, removePluginFromSettings:false, removePluginSettings:false, checkModified: false);
_modifiedPlugins.Add(existingVersion.ID);
}
@@ -561,12 +562,13 @@ namespace Flow.Launcher.Core.Plugin
#region Internal functions
- internal static void InstallPlugin(UserPlugin plugin, string zipFilePath, bool checkModified)
+ internal static bool InstallPlugin(UserPlugin plugin, string zipFilePath, bool checkModified)
{
if (checkModified && PluginModified(plugin.ID))
{
- // Distinguish exception from installing same or less version
- throw new ArgumentException($"Plugin {plugin.Name} {plugin.ID} has been modified.", nameof(plugin));
+ API.ShowMsg(string.Format(API.GetTranslation("failedToInstallPluginTitle"), plugin.Name),
+ API.GetTranslation("pluginModifiedAlreadyMessage"));
+ return false;
}
// Unzip plugin files to temp folder
@@ -584,12 +586,16 @@ namespace Flow.Launcher.Core.Plugin
if (string.IsNullOrEmpty(metadataJsonFilePath) || string.IsNullOrEmpty(pluginFolderPath))
{
- throw new FileNotFoundException($"Unable to find plugin.json from the extracted zip file, or this path {pluginFolderPath} does not exist");
+ API.ShowMsg(string.Format(API.GetTranslation("failedToInstallPluginTitle"), plugin.Name),
+ string.Format(API.GetTranslation("fileNotFoundMessage"), pluginFolderPath));
+ return false;
}
if (SameOrLesserPluginVersionExists(metadataJsonFilePath))
{
- throw new InvalidOperationException($"A plugin with the same ID and version already exists, or the version is greater than this downloaded plugin {plugin.Name}");
+ API.ShowMsg(string.Format(API.GetTranslation("failedToInstallPluginTitle"), plugin.Name),
+ API.GetTranslation("pluginExistAlreadyMessage"));
+ return false;
}
var folderName = string.IsNullOrEmpty(plugin.Version) ? $"{plugin.Name}-{Guid.NewGuid()}" : $"{plugin.Name}-{plugin.Version}";
@@ -633,13 +639,17 @@ namespace Flow.Launcher.Core.Plugin
{
_modifiedPlugins.Add(plugin.ID);
}
+
+ return true;
}
internal static async Task UninstallPluginAsync(PluginMetadata plugin, bool removePluginFromSettings, bool removePluginSettings, bool checkModified)
{
if (checkModified && PluginModified(plugin.ID))
{
- throw new ArgumentException($"Plugin {plugin.Name} has been modified");
+ API.ShowMsg(string.Format(API.GetTranslation("failedToUninstallPluginTitle"), plugin.Name),
+ API.GetTranslation("pluginModifiedAlreadyMessage"));
+ return;
}
if (removePluginSettings || removePluginFromSettings)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index e71ece19d..1cc03d6b1 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -175,6 +175,11 @@
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
+ Fail to install {0}
+ Fail to uninstall {0}
+ This plugin has been installed or uninstalled already, please restart Flow
+ Unable to find plugin.json from the extracted zip file, or this path {0} does not exist
+ A plugin with the same ID and version already exists, or the version is greater than this downloaded plugin
Plugin Store
From 6318bbe1878d54ebc2c19670e6a9d06e1035b95b Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 30 Jun 2025 13:16:59 +0800
Subject: [PATCH 1608/1697] Fix an issue that pm install/uninstall same plugin
without restart says correct message but another message also pops up to say
it's successfully installed
---
Flow.Launcher.Core/Plugin/PluginInstaller.cs | 21 ++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/Flow.Launcher.Core/Plugin/PluginInstaller.cs b/Flow.Launcher.Core/Plugin/PluginInstaller.cs
index 781ad3ff0..4cdab09f9 100644
--- a/Flow.Launcher.Core/Plugin/PluginInstaller.cs
+++ b/Flow.Launcher.Core/Plugin/PluginInstaller.cs
@@ -27,6 +27,13 @@ public static class PluginInstaller
public static async Task InstallPluginAndCheckRestartAsync(UserPlugin newPlugin)
{
+ if (API.PluginModified(newPlugin.ID))
+ {
+ API.ShowMsg(string.Format(API.GetTranslation("failedToInstallPluginTitle"), newPlugin.Name),
+ API.GetTranslation("pluginModifiedAlreadyMessage"));
+ return;
+ }
+
if (API.ShowMsgBox(
string.Format(
API.GetTranslation("InstallPromptSubtitle"),
@@ -117,6 +124,13 @@ public static class PluginInstaller
return;
}
+ if (API.PluginModified(plugin.ID))
+ {
+ API.ShowMsg(string.Format(API.GetTranslation("failedToInstallPluginTitle"), plugin.Name),
+ API.GetTranslation("pluginModifiedAlreadyMessage"));
+ return;
+ }
+
if (Settings.ShowUnknownSourceWarning)
{
if (!InstallSourceKnown(plugin.Website)
@@ -132,6 +146,13 @@ public static class PluginInstaller
public static async Task UninstallPluginAndCheckRestartAsync(PluginMetadata oldPlugin)
{
+ if (API.PluginModified(oldPlugin.ID))
+ {
+ API.ShowMsg(string.Format(API.GetTranslation("failedToUninstallPluginTitle"), oldPlugin.Name),
+ API.GetTranslation("pluginModifiedAlreadyMessage"));
+ return;
+ }
+
if (API.ShowMsgBox(
string.Format(
API.GetTranslation("UninstallPromptSubtitle"),
From 0c1fcad06f8df0a654b4b476fcf9c22321db41b5 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 30 Jun 2025 14:39:29 +0800
Subject: [PATCH 1609/1697] Fix grid row issue
---
Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml
index 284ad32ad..0daa36e63 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml
@@ -44,7 +44,7 @@
TextWrapping="Wrap" />
-
+