Skip to content

Commit f25c5b9

Browse files
committed
Improve code quality & Use progress name and id as title tooltip
1 parent 8ee2d48 commit f25c5b9

File tree

4 files changed

+100
-69
lines changed

4 files changed

+100
-69
lines changed

Plugins/Flow.Launcher.Plugin.ProcessKiller/Flow.Launcher.Plugin.ProcessKiller.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@
5858
</ItemGroup>
5959

6060
<ItemGroup>
61-
<ProjectReference Include="..\..\Flow.Launcher.Infrastructure\Flow.Launcher.Infrastructure.csproj" />
6261
<ProjectReference Include="..\..\Flow.Launcher.Plugin\Flow.Launcher.Plugin.csproj" />
6362
</ItemGroup>
6463

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

Lines changed: 73 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
using System.Collections.Generic;
1+
using System;
2+
using System.Collections.Generic;
23
using System.Linq;
3-
using Flow.Launcher.Infrastructure;
44

55
namespace Flow.Launcher.Plugin.ProcessKiller
66
{
@@ -48,7 +48,7 @@ public List<Result> LoadContextMenus(Result result)
4848
{
4949
foreach (var p in similarProcesses)
5050
{
51-
processHelper.TryKill(p);
51+
processHelper.TryKill(_context, p);
5252
}
5353

5454
return true;
@@ -60,73 +60,113 @@ public List<Result> LoadContextMenus(Result result)
6060
return menuOptions;
6161
}
6262

63-
private record RunningProcessInfo(string ProcessName, string MainWindowTitle);
64-
6563
private List<Result> CreateResultsFromQuery(Query query)
6664
{
67-
var searchTerm = query.Search;
68-
var processWindowTitle = ProcessHelper.GetProcessesWithNonEmptyWindowTitle();
69-
var processList = processHelper.GetMatchingProcesses(searchTerm, processWindowTitle);
70-
71-
if (!processList.Any())
65+
// Get all non-system processes
66+
var allPocessList = processHelper.GetMatchingProcesses();
67+
if (!allPocessList.Any())
7268
{
7369
return null;
7470
}
7571

76-
var results = new List<Result>();
77-
foreach (var pr in processList)
72+
// Filter processes based on search term
73+
var searchTerm = query.Search;
74+
var processlist = new List<ProcessResult>();
75+
var processWindowTitle = ProcessHelper.GetProcessesWithNonEmptyWindowTitle();
76+
if (string.IsNullOrWhiteSpace(searchTerm))
7877
{
79-
var p = pr.Process;
80-
var path = processHelper.TryGetProcessFilename(p);
81-
var title = p.ProcessName + " - " + p.Id;
82-
var score = pr.Score;
83-
if (processWindowTitle.TryGetValue(p.Id, out var mainWindowTitle))
78+
foreach (var p in allPocessList)
8479
{
85-
title = mainWindowTitle;
86-
if (string.IsNullOrWhiteSpace(searchTerm))
80+
var progressNameIdTitle = ProcessHelper.GetProcessNameIdTitle(p);
81+
82+
if (processWindowTitle.TryGetValue(p.Id, out var windowTitle))
8783
{
8884
// Add score to prioritize processes with visible windows
89-
score += 200;
85+
// And use window title for those processes
86+
processlist.Add(new ProcessResult(p, 200, windowTitle, null, progressNameIdTitle));
87+
}
88+
else
89+
{
90+
processlist.Add(new ProcessResult(p, 0, progressNameIdTitle, null, progressNameIdTitle));
9091
}
9192
}
93+
}
94+
else
95+
{
96+
foreach (var p in allPocessList)
97+
{
98+
var progressNameIdTitle = ProcessHelper.GetProcessNameIdTitle(p);
99+
100+
if (processWindowTitle.TryGetValue(p.Id, out var windowTitle))
101+
{
102+
// Get max score from searching process name, window title and process id
103+
var windowTitleMatch = _context.API.FuzzySearch(searchTerm, windowTitle);
104+
var processNameIdMatch = _context.API.FuzzySearch(searchTerm, progressNameIdTitle);
105+
var score = Math.Max(windowTitleMatch.Score, processNameIdMatch.Score);
106+
if (score > 0)
107+
{
108+
// Add score to prioritize processes with visible windows
109+
// And use window title for those processes
110+
score += 200;
111+
processlist.Add(new ProcessResult(p, score, windowTitle,
112+
score == windowTitleMatch.Score ? windowTitleMatch : null, progressNameIdTitle));
113+
}
114+
}
115+
else
116+
{
117+
var processNameIdMatch = _context.API.FuzzySearch(searchTerm, progressNameIdTitle);
118+
var score = processNameIdMatch.Score;
119+
if (score > 0)
120+
{
121+
processlist.Add(new ProcessResult(p, score, progressNameIdTitle, processNameIdMatch, progressNameIdTitle));
122+
}
123+
}
124+
}
125+
}
126+
127+
var results = new List<Result>();
128+
foreach (var pr in processlist)
129+
{
130+
var p = pr.Process;
131+
var path = processHelper.TryGetProcessFilename(p);
92132
results.Add(new Result()
93133
{
94134
IcoPath = path,
95-
Title = title,
135+
Title = pr.Title,
136+
TitleToolTip = pr.Tooltip,
96137
SubTitle = path,
97-
TitleHighlightData = StringMatcher.FuzzySearch(searchTerm, p.ProcessName).MatchData,
98-
Score = score,
99-
ContextData = new RunningProcessInfo(p.ProcessName, mainWindowTitle),
138+
TitleHighlightData = pr.TitleMatch?.MatchData,
139+
Score = pr.Score,
140+
ContextData = p.ProcessName,
100141
AutoCompleteText = $"{_context.CurrentPluginMetadata.ActionKeyword}{Plugin.Query.TermSeparator}{p.ProcessName}",
101142
Action = (c) =>
102143
{
103-
processHelper.TryKill(p);
144+
processHelper.TryKill(_context, p);
104145
_context.API.ReQuery();
105146
return false;
106147
}
107148
});
108149
}
109150

110-
var sortedResults = results
111-
.OrderBy(x => x.Title)
112-
.ToList();
151+
// Order results by process name for processes without visible windows
152+
var sortedResults = results.OrderBy(x => x.Title).ToList();
113153

114154
// When there are multiple results AND all of them are instances of the same executable
115155
// add a quick option to kill them all at the top of the results.
116156
var firstResult = sortedResults.FirstOrDefault(x => !string.IsNullOrEmpty(x.SubTitle));
117-
if (processList.Count > 1 && !string.IsNullOrEmpty(searchTerm) && sortedResults.All(r => r.SubTitle == firstResult?.SubTitle))
157+
if (processlist.Count > 1 && !string.IsNullOrEmpty(searchTerm) && sortedResults.All(r => r.SubTitle == firstResult?.SubTitle))
118158
{
119159
sortedResults.Insert(1, new Result()
120160
{
121161
IcoPath = firstResult?.IcoPath,
122-
Title = string.Format(_context.API.GetTranslation("flowlauncher_plugin_processkiller_kill_all"), ((RunningProcessInfo)firstResult?.ContextData).ProcessName),
123-
SubTitle = string.Format(_context.API.GetTranslation("flowlauncher_plugin_processkiller_kill_all_count"), processList.Count),
162+
Title = string.Format(_context.API.GetTranslation("flowlauncher_plugin_processkiller_kill_all"), firstResult?.ContextData),
163+
SubTitle = string.Format(_context.API.GetTranslation("flowlauncher_plugin_processkiller_kill_all_count"), processlist.Count),
124164
Score = 200,
125165
Action = (c) =>
126166
{
127-
foreach (var p in processList)
167+
foreach (var p in processlist)
128168
{
129-
processHelper.TryKill(p.Process);
169+
processHelper.TryKill(_context, p.Process);
130170
}
131171
_context.API.ReQuery();
132172
return false;

Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs

Lines changed: 15 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
using Flow.Launcher.Infrastructure;
2-
using Flow.Launcher.Infrastructure.Logger;
3-
using Microsoft.Win32.SafeHandles;
1+
using Microsoft.Win32.SafeHandles;
42
using System;
53
using System.Collections.Generic;
64
using System.Diagnostics;
@@ -37,41 +35,25 @@ private bool IsSystemProcess(Process p) => _systemProcessList.Contains(p.Process
3735
string.Compare(p.ProcessName, FlowLauncherProcessName, StringComparison.OrdinalIgnoreCase) == 0;
3836

3937
/// <summary>
40-
/// Returns a ProcessResult for evey running non-system process whose name matches the given searchTerm
38+
/// Get title based on process name and id
4139
/// </summary>
42-
public List<ProcessResult> GetMatchingProcesses(string searchTerm, Dictionary<int, string> processWindowTitle)
40+
public static string GetProcessNameIdTitle(Process p)
4341
{
44-
var processlist = new List<ProcessResult>();
42+
return p.ProcessName + " - " + p.Id;
43+
}
44+
45+
/// <summary>
46+
/// Returns a Process for evey running non-system process
47+
/// </summary>
48+
public List<Process> GetMatchingProcesses()
49+
{
50+
var processlist = new List<Process>();
4551

4652
foreach (var p in Process.GetProcesses())
4753
{
4854
if (IsSystemProcess(p)) continue;
4955

50-
if (string.IsNullOrWhiteSpace(searchTerm))
51-
{
52-
// Show all non-system processes
53-
processlist.Add(new ProcessResult(p, 0));
54-
}
55-
else
56-
{
57-
// Search window title first
58-
if (processWindowTitle.TryGetValue(p.Id, out var windowTitle))
59-
{
60-
var score = StringMatcher.FuzzySearch(searchTerm, windowTitle).Score;
61-
if (score > 0)
62-
{
63-
processlist.Add(new ProcessResult(p, score));
64-
}
65-
}
66-
67-
// Search process name and process id
68-
var score1 = StringMatcher.FuzzySearch(searchTerm, p.ProcessName + " - " + p.Id).Score;
69-
if (score1 > 0)
70-
{
71-
processlist.Add(new ProcessResult(p, score1));
72-
continue;
73-
}
74-
}
56+
processlist.Add(p);
7557
}
7658

7759
return processlist;
@@ -131,7 +113,7 @@ public IEnumerable<Process> GetSimilarProcesses(string processPath)
131113
return Process.GetProcesses().Where(p => !IsSystemProcess(p) && TryGetProcessFilename(p) == processPath);
132114
}
133115

134-
public void TryKill(Process p)
116+
public void TryKill(PluginInitContext context, Process p)
135117
{
136118
try
137119
{
@@ -143,7 +125,7 @@ public void TryKill(Process p)
143125
}
144126
catch (Exception e)
145127
{
146-
Log.Exception($"{nameof(ProcessHelper)}", $"Failed to kill process {p.ProcessName}", e);
128+
context.API.LogException($"{nameof(ProcessHelper)}", $"Failed to kill process {p.ProcessName}", e);
147129
}
148130
}
149131

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,27 @@
11
using System.Diagnostics;
2+
using Flow.Launcher.Plugin.SharedModels;
23

34
namespace Flow.Launcher.Plugin.ProcessKiller
45
{
56
internal class ProcessResult
67
{
7-
public ProcessResult(Process process, int score)
8+
public ProcessResult(Process process, int score, string title, MatchResult match, string tooltip)
89
{
910
Process = process;
1011
Score = score;
12+
Title = title;
13+
TitleMatch = match;
14+
Tooltip = tooltip;
1115
}
1216

1317
public Process Process { get; }
1418

1519
public int Score { get; }
20+
21+
public string Title { get; }
22+
23+
public MatchResult TitleMatch { get; }
24+
25+
public string Tooltip { get; }
1626
}
17-
}
27+
}

0 commit comments

Comments
 (0)