Skip to content

Commit e028ed3

Browse files
authored
Merge pull request #3259 from Jack251970/remove_duplicated_programs
Support removing duplicated programs
2 parents c7218fb + 79bcf8b commit e028ed3

File tree

5 files changed

+69
-25
lines changed

5 files changed

+69
-25
lines changed

Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
<system:String x:Key="flowlauncher_plugin_program_enable_hideuninstallers_tooltip">Hides programs with common uninstaller names, such as unins000.exe</system:String>
3737
<system:String x:Key="flowlauncher_plugin_program_enable_description">Search in Program Description</system:String>
3838
<system:String x:Key="flowlauncher_plugin_program_enable_description_tooltip">Flow will search program's description</system:String>
39+
<system:String x:Key="flowlauncher_plugin_program_enable_hideduplicatedwindowsapp">Hide duplicated apps</system:String>
40+
<system:String x:Key="flowlauncher_plugin_program_enable_hideduplicatedwindowsapp_tooltip">Hide duplicated Win32 programs that are already in the UWP list</system:String>
3941
<system:String x:Key="flowlauncher_plugin_program_suffixes_header">Suffixes</system:String>
4042
<system:String x:Key="flowlauncher_plugin_program_max_depth_header">Max Depth</system:String>
4143

Plugins/Flow.Launcher.Plugin.Program/Main.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ public class Main : ISettingProvider, IAsyncPlugin, IPluginI18n, IContextMenu, I
7272
private const string ExeUninstallerSuffix = ".exe";
7373
private const string InkUninstallerSuffix = ".lnk";
7474

75+
private static readonly string WindowsAppPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "WindowsApps");
76+
7577
static Main()
7678
{
7779
}
@@ -90,11 +92,20 @@ public async Task<List<Result>> QueryAsync(Query query, CancellationToken token)
9092
{
9193
try
9294
{
95+
// Collect all UWP Windows app directories
96+
var uwpsDirectories = _settings.HideDuplicatedWindowsApp ? _uwps
97+
.Where(uwp => !string.IsNullOrEmpty(uwp.Location)) // Exclude invalid paths
98+
.Where(uwp => uwp.Location.StartsWith(WindowsAppPath, StringComparison.OrdinalIgnoreCase)) // Keep system apps
99+
.Select(uwp => uwp.Location.TrimEnd('\\')) // Remove trailing slash
100+
.Distinct(StringComparer.OrdinalIgnoreCase)
101+
.ToArray() : null;
102+
93103
return _win32s.Cast<IProgram>()
94104
.Concat(_uwps)
95105
.AsParallel()
96106
.WithCancellation(token)
97107
.Where(HideUninstallersFilter)
108+
.Where(p => HideDuplicatedWindowsAppFilter(p, uwpsDirectories))
98109
.Where(p => p.Enabled)
99110
.Select(p => p.Result(query.Search, Context.API))
100111
.Where(r => r?.Score > 0)
@@ -152,6 +163,23 @@ private bool HideUninstallersFilter(IProgram program)
152163
return true;
153164
}
154165

166+
private static bool HideDuplicatedWindowsAppFilter(IProgram program, string[] uwpsDirectories)
167+
{
168+
if (uwpsDirectories == null || uwpsDirectories.Length == 0) return true;
169+
if (program is UWPApp) return true;
170+
171+
var location = program.Location.TrimEnd('\\'); // Ensure trailing slash
172+
if (string.IsNullOrEmpty(location))
173+
return true; // Keep if location is invalid
174+
175+
if (!location.StartsWith(WindowsAppPath, StringComparison.OrdinalIgnoreCase))
176+
return true; // Keep if not a Windows app
177+
178+
// Check if the any Win32 executable directory contains UWP Windows app location matches
179+
return !uwpsDirectories.Any(uwpDirectory =>
180+
location.StartsWith(uwpDirectory, StringComparison.OrdinalIgnoreCase));
181+
}
182+
155183
public async Task InitAsync(PluginInitContext context)
156184
{
157185
Context = context;

Plugins/Flow.Launcher.Plugin.Program/Settings.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ private void RemoveRedundantSuffixes()
121121
public bool EnableRegistrySource { get; set; } = true;
122122
public bool EnablePathSource { get; set; } = false;
123123
public bool EnableUWP { get; set; } = true;
124+
public bool HideDuplicatedWindowsApp { get; set; } = false;
124125

125126
internal const char SuffixSeparator = ';';
126127
}

Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
DataContext="{Binding RelativeSource={RelativeSource Self}}"
99
mc:Ignorable="d">
1010
<UserControl.Resources>
11-
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
11+
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
1212
</UserControl.Resources>
1313
<Grid Margin="0">
1414
<Grid.RowDefinitions>
@@ -18,40 +18,40 @@
1818
<RowDefinition Height="Auto" />
1919
</Grid.RowDefinitions>
2020
<DockPanel
21-
Margin="70,10,0,8"
21+
Margin="70 10 0 8"
2222
HorizontalAlignment="Stretch"
2323
LastChildFill="True">
2424
<TextBlock
2525
MinWidth="120"
26-
Margin="0,5,10,0"
26+
Margin="0 5 10 0"
2727
Text="{DynamicResource flowlauncher_plugin_program_index_source}" />
2828
<WrapPanel
2929
Width="Auto"
30-
Margin="0,0,14,0"
30+
Margin="0 0 14 0"
3131
HorizontalAlignment="Right"
3232
DockPanel.Dock="Right">
3333
<CheckBox
3434
Name="UWPEnabled"
35-
Margin="12,0,12,0"
36-
Visibility="{Binding ShowUWPCheckbox, Converter={StaticResource BooleanToVisibilityConverter}}"
35+
Margin="12 0 12 0"
3736
Content="{DynamicResource flowlauncher_plugin_program_index_uwp}"
3837
IsChecked="{Binding EnableUWP}"
39-
ToolTip="{DynamicResource flowlauncher_plugin_program_index_uwp_tooltip}" />
38+
ToolTip="{DynamicResource flowlauncher_plugin_program_index_uwp_tooltip}"
39+
Visibility="{Binding ShowUWPCheckbox, Converter={StaticResource BooleanToVisibilityConverter}}" />
4040
<CheckBox
4141
Name="StartMenuEnabled"
42-
Margin="12,0,12,0"
42+
Margin="12 0 12 0"
4343
Content="{DynamicResource flowlauncher_plugin_program_index_start}"
4444
IsChecked="{Binding EnableStartMenuSource}"
4545
ToolTip="{DynamicResource flowlauncher_plugin_program_index_start_tooltip}" />
4646
<CheckBox
4747
Name="RegistryEnabled"
48-
Margin="12,0,12,0"
48+
Margin="12 0 12 0"
4949
Content="{DynamicResource flowlauncher_plugin_program_index_registry}"
5050
IsChecked="{Binding EnableRegistrySource}"
5151
ToolTip="{DynamicResource flowlauncher_plugin_program_index_registry_tooltip}" />
5252
<CheckBox
5353
Name="PATHEnabled"
54-
Margin="12,0,12,0"
54+
Margin="12 0 12 0"
5555
Content="{DynamicResource flowlauncher_plugin_program_index_PATH}"
5656
IsChecked="{Binding EnablePATHSource}"
5757
ToolTip="{DynamicResource flowlauncher_plugin_program_index_PATH_tooltip}" />
@@ -67,21 +67,20 @@
6767
BorderBrush="{DynamicResource Color03B}"
6868
BorderThickness="1" />
6969
<DockPanel
70-
Margin="70,10,0,8"
70+
Margin="70 10 0 8"
7171
HorizontalAlignment="Stretch"
7272
LastChildFill="True">
7373
<TextBlock
7474
MinWidth="120"
75-
Margin="0,5,10,0"
75+
Margin="0 5 10 0"
7676
Text="{DynamicResource flowlauncher_plugin_program_index_option}" />
7777
<WrapPanel
7878
Width="Auto"
79-
Margin="0,0,14,0"
79+
Margin="0 0 14 0"
8080
HorizontalAlignment="Right"
8181
DockPanel.Dock="Right">
8282
<CheckBox
83-
Name="HideLnkEnabled"
84-
Margin="12,0,12,0"
83+
Margin="12 0 12 0"
8584
Content="{DynamicResource flowlauncher_plugin_program_enable_hidelnkpath}"
8685
IsChecked="{Binding HideAppsPath}"
8786
ToolTip="{DynamicResource flowlauncher_plugin_program_enable_hidelnkpath_tooltip}" />
@@ -91,40 +90,44 @@
9190
IsChecked="{Binding HideUninstallers}"
9291
ToolTip="{DynamicResource flowlauncher_plugin_program_enable_hideuninstallers_tooltip}" />
9392
<CheckBox
94-
Name="DescriptionEnabled"
95-
Margin="12,0,12,0"
93+
Margin="12 0 12 0"
9694
Content="{DynamicResource flowlauncher_plugin_program_enable_description}"
9795
IsChecked="{Binding EnableDescription}"
9896
ToolTip="{DynamicResource flowlauncher_plugin_program_enable_description_tooltip}" />
97+
<CheckBox
98+
Margin="12 0 12 0"
99+
Content="{DynamicResource flowlauncher_plugin_program_enable_hideduplicatedwindowsapp}"
100+
IsChecked="{Binding HideDuplicatedWindowsApp}"
101+
ToolTip="{DynamicResource flowlauncher_plugin_program_enable_hideduplicatedwindowsapp_tooltip}" />
99102
</WrapPanel>
100103
</DockPanel>
101104
<Separator
102105
Height="1"
103106
BorderBrush="{DynamicResource Color03B}"
104107
BorderThickness="1" />
105108
<StackPanel
106-
Margin="60,0,0,2"
109+
Margin="60 0 0 2"
107110
HorizontalAlignment="Left"
108111
VerticalAlignment="Center"
109112
Orientation="Horizontal">
110113
<Button
111114
x:Name="btnLoadAllProgramSource"
112115
MinWidth="120"
113-
Margin="10,10,5,10"
116+
Margin="10 10 5 10"
114117
HorizontalAlignment="Right"
115118
Click="btnLoadAllProgramSource_OnClick"
116119
Content="{DynamicResource flowlauncher_plugin_program_all_programs}" />
117120
<Button
118121
x:Name="btnProgramSuffixes"
119122
MinWidth="120"
120-
Margin="5,10,5,10"
123+
Margin="5 10 5 10"
121124
HorizontalAlignment="Right"
122125
Click="BtnProgramSuffixes_OnClick"
123126
Content="{DynamicResource flowlauncher_plugin_program_suffixes}" />
124127
<Button
125128
x:Name="btnReindex"
126129
MinWidth="120"
127-
Margin="5,10,5,10"
130+
Margin="5 10 5 10"
128131
HorizontalAlignment="Right"
129132
Click="btnReindex_Click"
130133
Content="{DynamicResource flowlauncher_plugin_program_reindex}" />
@@ -142,7 +145,7 @@
142145
Minimum="0" />
143146
<TextBlock
144147
Height="20"
145-
Margin="10,0,0,0"
148+
Margin="10 0 0 0"
146149
HorizontalAlignment="Center"
147150
Text="{DynamicResource flowlauncher_plugin_program_indexing}" />
148151
</StackPanel>
@@ -151,7 +154,7 @@
151154
<ListView
152155
x:Name="programSourceView"
153156
Grid.Row="2"
154-
Margin="70,0,20,0"
157+
Margin="70 0 20 0"
155158
AllowDrop="True"
156159
BorderBrush="DarkGray"
157160
BorderThickness="1"
@@ -203,7 +206,7 @@
203206
<DockPanel
204207
Grid.Row="3"
205208
Grid.RowSpan="1"
206-
Margin="0,0,20,0">
209+
Margin="0 0 20 0">
207210
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
208211
<Button
209212
x:Name="btnProgramSourceStatus"
@@ -220,7 +223,7 @@
220223
<Button
221224
x:Name="btnAddProgramSource"
222225
MinWidth="100"
223-
Margin="10,10,0,10"
226+
Margin="10 10 0 10"
224227
Click="btnAddProgramSource_OnClick"
225228
Content="{DynamicResource flowlauncher_plugin_program_add}" />
226229
</StackPanel>

Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,16 @@ public bool HideUninstallers
5757
}
5858
}
5959

60+
public bool HideDuplicatedWindowsApp
61+
{
62+
get => _settings.HideDuplicatedWindowsApp;
63+
set
64+
{
65+
Main.ResetCache();
66+
_settings.HideDuplicatedWindowsApp = value;
67+
}
68+
}
69+
6070
public bool EnableRegistrySource
6171
{
6272
get => _settings.EnableRegistrySource;

0 commit comments

Comments
 (0)