mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Improve code quality & Use progress name and id as title tooltip
This commit is contained in:
parent
8ee2d4852e
commit
f25c5b9b05
4 changed files with 102 additions and 71 deletions
|
|
@ -58,7 +58,6 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Flow.Launcher.Infrastructure\Flow.Launcher.Infrastructure.csproj" />
|
||||
<ProjectReference Include="..\..\Flow.Launcher.Plugin\Flow.Launcher.Plugin.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Flow.Launcher.Infrastructure;
|
||||
|
||||
namespace Flow.Launcher.Plugin.ProcessKiller
|
||||
{
|
||||
|
|
@ -48,7 +48,7 @@ namespace Flow.Launcher.Plugin.ProcessKiller
|
|||
{
|
||||
foreach (var p in similarProcesses)
|
||||
{
|
||||
processHelper.TryKill(p);
|
||||
processHelper.TryKill(_context, p);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -60,73 +60,113 @@ namespace Flow.Launcher.Plugin.ProcessKiller
|
|||
return menuOptions;
|
||||
}
|
||||
|
||||
private record RunningProcessInfo(string ProcessName, string MainWindowTitle);
|
||||
|
||||
private List<Result> CreateResultsFromQuery(Query query)
|
||||
{
|
||||
var searchTerm = query.Search;
|
||||
var processWindowTitle = ProcessHelper.GetProcessesWithNonEmptyWindowTitle();
|
||||
var processList = processHelper.GetMatchingProcesses(searchTerm, processWindowTitle);
|
||||
|
||||
if (!processList.Any())
|
||||
// Get all non-system processes
|
||||
var allPocessList = processHelper.GetMatchingProcesses();
|
||||
if (!allPocessList.Any())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Filter processes based on search term
|
||||
var searchTerm = query.Search;
|
||||
var processlist = new List<ProcessResult>();
|
||||
var processWindowTitle = ProcessHelper.GetProcessesWithNonEmptyWindowTitle();
|
||||
if (string.IsNullOrWhiteSpace(searchTerm))
|
||||
{
|
||||
foreach (var p in allPocessList)
|
||||
{
|
||||
var progressNameIdTitle = ProcessHelper.GetProcessNameIdTitle(p);
|
||||
|
||||
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, 200, windowTitle, null, progressNameIdTitle));
|
||||
}
|
||||
else
|
||||
{
|
||||
processlist.Add(new ProcessResult(p, 0, progressNameIdTitle, null, progressNameIdTitle));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var p in allPocessList)
|
||||
{
|
||||
var progressNameIdTitle = ProcessHelper.GetProcessNameIdTitle(p);
|
||||
|
||||
if (processWindowTitle.TryGetValue(p.Id, out var windowTitle))
|
||||
{
|
||||
// Get max score from searching process name, window title and process id
|
||||
var windowTitleMatch = _context.API.FuzzySearch(searchTerm, windowTitle);
|
||||
var processNameIdMatch = _context.API.FuzzySearch(searchTerm, progressNameIdTitle);
|
||||
var score = Math.Max(windowTitleMatch.Score, processNameIdMatch.Score);
|
||||
if (score > 0)
|
||||
{
|
||||
// Add score to prioritize processes with visible windows
|
||||
// And use window title for those processes
|
||||
score += 200;
|
||||
processlist.Add(new ProcessResult(p, score, windowTitle,
|
||||
score == windowTitleMatch.Score ? windowTitleMatch : null, progressNameIdTitle));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var processNameIdMatch = _context.API.FuzzySearch(searchTerm, progressNameIdTitle);
|
||||
var score = processNameIdMatch.Score;
|
||||
if (score > 0)
|
||||
{
|
||||
processlist.Add(new ProcessResult(p, score, progressNameIdTitle, processNameIdMatch, progressNameIdTitle));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var results = new List<Result>();
|
||||
foreach (var pr in processList)
|
||||
foreach (var pr in processlist)
|
||||
{
|
||||
var p = pr.Process;
|
||||
var path = processHelper.TryGetProcessFilename(p);
|
||||
var title = p.ProcessName + " - " + p.Id;
|
||||
var score = pr.Score;
|
||||
if (processWindowTitle.TryGetValue(p.Id, out var mainWindowTitle))
|
||||
{
|
||||
title = mainWindowTitle;
|
||||
if (string.IsNullOrWhiteSpace(searchTerm))
|
||||
{
|
||||
// Add score to prioritize processes with visible windows
|
||||
score += 200;
|
||||
}
|
||||
}
|
||||
results.Add(new Result()
|
||||
{
|
||||
IcoPath = path,
|
||||
Title = title,
|
||||
Title = pr.Title,
|
||||
TitleToolTip = pr.Tooltip,
|
||||
SubTitle = path,
|
||||
TitleHighlightData = StringMatcher.FuzzySearch(searchTerm, p.ProcessName).MatchData,
|
||||
Score = score,
|
||||
ContextData = new RunningProcessInfo(p.ProcessName, mainWindowTitle),
|
||||
TitleHighlightData = pr.TitleMatch?.MatchData,
|
||||
Score = pr.Score,
|
||||
ContextData = p.ProcessName,
|
||||
AutoCompleteText = $"{_context.CurrentPluginMetadata.ActionKeyword}{Plugin.Query.TermSeparator}{p.ProcessName}",
|
||||
Action = (c) =>
|
||||
{
|
||||
processHelper.TryKill(p);
|
||||
processHelper.TryKill(_context, p);
|
||||
_context.API.ReQuery();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var sortedResults = results
|
||||
.OrderBy(x => x.Title)
|
||||
.ToList();
|
||||
// Order results by process name for processes without visible windows
|
||||
var sortedResults = results.OrderBy(x => x.Title).ToList();
|
||||
|
||||
// When there are multiple results AND all of them are instances of the same executable
|
||||
// add a quick option to kill them all at the top of the results.
|
||||
var firstResult = sortedResults.FirstOrDefault(x => !string.IsNullOrEmpty(x.SubTitle));
|
||||
if (processList.Count > 1 && !string.IsNullOrEmpty(searchTerm) && sortedResults.All(r => r.SubTitle == firstResult?.SubTitle))
|
||||
if (processlist.Count > 1 && !string.IsNullOrEmpty(searchTerm) && sortedResults.All(r => r.SubTitle == firstResult?.SubTitle))
|
||||
{
|
||||
sortedResults.Insert(1, new Result()
|
||||
{
|
||||
IcoPath = firstResult?.IcoPath,
|
||||
Title = string.Format(_context.API.GetTranslation("flowlauncher_plugin_processkiller_kill_all"), ((RunningProcessInfo)firstResult?.ContextData).ProcessName),
|
||||
SubTitle = string.Format(_context.API.GetTranslation("flowlauncher_plugin_processkiller_kill_all_count"), processList.Count),
|
||||
Title = string.Format(_context.API.GetTranslation("flowlauncher_plugin_processkiller_kill_all"), firstResult?.ContextData),
|
||||
SubTitle = string.Format(_context.API.GetTranslation("flowlauncher_plugin_processkiller_kill_all_count"), processlist.Count),
|
||||
Score = 200,
|
||||
Action = (c) =>
|
||||
{
|
||||
foreach (var p in processList)
|
||||
foreach (var p in processlist)
|
||||
{
|
||||
processHelper.TryKill(p.Process);
|
||||
processHelper.TryKill(_context, p.Process);
|
||||
}
|
||||
_context.API.ReQuery();
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
using Flow.Launcher.Infrastructure;
|
||||
using Flow.Launcher.Infrastructure.Logger;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
|
@ -37,41 +35,25 @@ namespace Flow.Launcher.Plugin.ProcessKiller
|
|||
string.Compare(p.ProcessName, FlowLauncherProcessName, StringComparison.OrdinalIgnoreCase) == 0;
|
||||
|
||||
/// <summary>
|
||||
/// Returns a ProcessResult for evey running non-system process whose name matches the given searchTerm
|
||||
/// Get title based on process name and id
|
||||
/// </summary>
|
||||
public List<ProcessResult> GetMatchingProcesses(string searchTerm, Dictionary<int, string> processWindowTitle)
|
||||
public static string GetProcessNameIdTitle(Process p)
|
||||
{
|
||||
var processlist = new List<ProcessResult>();
|
||||
return p.ProcessName + " - " + p.Id;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a Process for evey running non-system process
|
||||
/// </summary>
|
||||
public List<Process> GetMatchingProcesses()
|
||||
{
|
||||
var processlist = new List<Process>();
|
||||
|
||||
foreach (var p in Process.GetProcesses())
|
||||
{
|
||||
if (IsSystemProcess(p)) continue;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(searchTerm))
|
||||
{
|
||||
// Show all non-system processes
|
||||
processlist.Add(new ProcessResult(p, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Search window title first
|
||||
if (processWindowTitle.TryGetValue(p.Id, out var windowTitle))
|
||||
{
|
||||
var score = StringMatcher.FuzzySearch(searchTerm, windowTitle).Score;
|
||||
if (score > 0)
|
||||
{
|
||||
processlist.Add(new ProcessResult(p, score));
|
||||
}
|
||||
}
|
||||
|
||||
// Search process name and process id
|
||||
var score1 = StringMatcher.FuzzySearch(searchTerm, p.ProcessName + " - " + p.Id).Score;
|
||||
if (score1 > 0)
|
||||
{
|
||||
processlist.Add(new ProcessResult(p, score1));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
processlist.Add(p);
|
||||
}
|
||||
|
||||
return processlist;
|
||||
|
|
@ -131,7 +113,7 @@ namespace Flow.Launcher.Plugin.ProcessKiller
|
|||
return Process.GetProcesses().Where(p => !IsSystemProcess(p) && TryGetProcessFilename(p) == processPath);
|
||||
}
|
||||
|
||||
public void TryKill(Process p)
|
||||
public void TryKill(PluginInitContext context, Process p)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -143,7 +125,7 @@ namespace Flow.Launcher.Plugin.ProcessKiller
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Exception($"{nameof(ProcessHelper)}", $"Failed to kill process {p.ProcessName}", e);
|
||||
context.API.LogException($"{nameof(ProcessHelper)}", $"Failed to kill process {p.ProcessName}", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,17 +1,27 @@
|
|||
using System.Diagnostics;
|
||||
using Flow.Launcher.Plugin.SharedModels;
|
||||
|
||||
namespace Flow.Launcher.Plugin.ProcessKiller
|
||||
{
|
||||
internal class ProcessResult
|
||||
{
|
||||
public ProcessResult(Process process, int score)
|
||||
public ProcessResult(Process process, int score, string title, MatchResult match, string tooltip)
|
||||
{
|
||||
Process = process;
|
||||
Score = score;
|
||||
Title = title;
|
||||
TitleMatch = match;
|
||||
Tooltip = tooltip;
|
||||
}
|
||||
|
||||
public Process Process { get; }
|
||||
|
||||
public int Score { get; }
|
||||
|
||||
public string Title { get; }
|
||||
|
||||
public MatchResult TitleMatch { get; }
|
||||
|
||||
public string Tooltip { get; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue