From b2532fc88e09977b2c62d4eec3b8ec1ec0dd43d6 Mon Sep 17 00:00:00 2001 From: "pp.stabrawa" Date: Fri, 27 Dec 2024 12:43:43 +0100 Subject: [PATCH 001/298] Order search result by window title --- .../Main.cs | 30 ++++++++----- .../ProcessHelper.cs | 44 ++++++++++++++++++- 2 files changed, 61 insertions(+), 13 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs index be2a2dd66..03b563c9b 100644 --- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using Flow.Launcher.Infrastructure; @@ -60,30 +60,33 @@ namespace Flow.Launcher.Plugin.ProcessKiller return menuOptions; } + private record RunningProcessInfo(string ProcessName, string MainWindowTitle); + private List CreateResultsFromQuery(Query query) { string termToSearch = query.Search; - var processlist = processHelper.GetMatchingProcesses(termToSearch); - - if (!processlist.Any()) + var processList = processHelper.GetMatchingProcesses(termToSearch); + var processWithNonEmptyMainWindowTitleList = processHelper.GetProcessesWithNonEmptyWindowTitle(); + + if (!processList.Any()) { return null; } var results = new List(); - foreach (var pr in processlist) + foreach (var pr in processList) { var p = pr.Process; var path = processHelper.TryGetProcessFilename(p); results.Add(new Result() { IcoPath = path, - Title = p.ProcessName + " - " + p.Id, + Title = processWithNonEmptyMainWindowTitleList.TryGetValue(p.Id, out var mainWindowTitle) ? mainWindowTitle : p.ProcessName + " - " + p.Id, SubTitle = path, TitleHighlightData = StringMatcher.FuzzySearch(termToSearch, p.ProcessName).MatchData, Score = pr.Score, - ContextData = p.ProcessName, + ContextData = new RunningProcessInfo(p.ProcessName, mainWindowTitle), AutoCompleteText = $"{_context.CurrentPluginMetadata.ActionKeyword}{Plugin.Query.TermSeparator}{p.ProcessName}", Action = (c) => { @@ -95,22 +98,25 @@ namespace Flow.Launcher.Plugin.ProcessKiller }); } - var sortedResults = results.OrderBy(x => x.Title).ToList(); + var sortedResults = results + .OrderBy(x => string.IsNullOrEmpty(((RunningProcessInfo)x.ContextData).MainWindowTitle)) + .ThenBy(x => x.Title) + .ToList(); // When there are multiple results AND all of them are instances of the same executable // add a quick option to kill them all at the top of the results. var firstResult = sortedResults.FirstOrDefault(x => !string.IsNullOrEmpty(x.SubTitle)); - if (processlist.Count > 1 && !string.IsNullOrEmpty(termToSearch) && sortedResults.All(r => r.SubTitle == firstResult?.SubTitle)) + if (processList.Count > 1 && !string.IsNullOrEmpty(termToSearch) && sortedResults.All(r => r.SubTitle == firstResult?.SubTitle)) { sortedResults.Insert(1, new Result() { IcoPath = firstResult?.IcoPath, - Title = string.Format(_context.API.GetTranslation("flowlauncher_plugin_processkiller_kill_all"), firstResult?.ContextData), - SubTitle = string.Format(_context.API.GetTranslation("flowlauncher_plugin_processkiller_kill_all_count"), processlist.Count), + Title = string.Format(_context.API.GetTranslation("flowlauncher_plugin_processkiller_kill_all"), ((RunningProcessInfo)firstResult?.ContextData).ProcessName), + SubTitle = string.Format(_context.API.GetTranslation("flowlauncher_plugin_processkiller_kill_all_count"), processList.Count), Score = 200, Action = (c) => { - foreach (var p in processlist) + foreach (var p in processList) { processHelper.TryKill(p.Process); } diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs b/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs index 0acc39fbb..5cc94dfdf 100644 --- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs +++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs @@ -1,4 +1,4 @@ -using Flow.Launcher.Infrastructure; +using Flow.Launcher.Infrastructure; using Flow.Launcher.Infrastructure.Logger; using System; using System.Collections.Generic; @@ -11,6 +11,20 @@ namespace Flow.Launcher.Plugin.ProcessKiller { internal class ProcessHelper { + [DllImport("user32.dll")] + private static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam); + + private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam); + + [DllImport("user32.dll", CharSet = CharSet.Unicode)] + private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount); + + [DllImport("user32.dll")] + private static extern bool IsWindowVisible(IntPtr hWnd); + + [DllImport("user32.dll")] + private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); + private readonly HashSet _systemProcessList = new HashSet() { "conhost", @@ -60,6 +74,34 @@ namespace Flow.Launcher.Plugin.ProcessKiller return processlist; } + /// + /// Returns a dictionary of process IDs and their window titles for processes that have a visible main window with a non-empty title. + /// + public Dictionary GetProcessesWithNonEmptyWindowTitle() + { + var processDict = new Dictionary(); + EnumWindows((hWnd, lParam) => + { + StringBuilder windowTitle = new StringBuilder(); + GetWindowText(hWnd, windowTitle, windowTitle.Capacity); + + if (!string.IsNullOrWhiteSpace(windowTitle.ToString()) && IsWindowVisible(hWnd)) + { + GetWindowThreadProcessId(hWnd, out var processId); + var process = Process.GetProcessById((int)processId); + + if (!processDict.ContainsKey((int)processId)) + { + processDict.Add((int)processId, windowTitle.ToString()); + } + } + + return true; + }, IntPtr.Zero); + + return processDict; + } + /// /// Returns all non-system processes whose file path matches the given processPath /// From 9880c362fd7196b2fc7792f82b533fc80a945eed Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Wed, 19 Feb 2025 23:31:26 +0800 Subject: [PATCH 002/298] Remove useless settings control & project reference --- .../Flow.Launcher.Plugin.Url.csproj | 1 - Plugins/Flow.Launcher.Plugin.Url/Main.cs | 10 +--------- .../SettingsControl.xaml | 17 ----------------- .../SettingsControl.xaml.cs | 18 ------------------ 4 files changed, 1 insertion(+), 45 deletions(-) delete mode 100644 Plugins/Flow.Launcher.Plugin.Url/SettingsControl.xaml delete mode 100644 Plugins/Flow.Launcher.Plugin.Url/SettingsControl.xaml.cs diff --git a/Plugins/Flow.Launcher.Plugin.Url/Flow.Launcher.Plugin.Url.csproj b/Plugins/Flow.Launcher.Plugin.Url/Flow.Launcher.Plugin.Url.csproj index 3db0cd0cb..6d338733e 100644 --- a/Plugins/Flow.Launcher.Plugin.Url/Flow.Launcher.Plugin.Url.csproj +++ b/Plugins/Flow.Launcher.Plugin.Url/Flow.Launcher.Plugin.Url.csproj @@ -42,7 +42,6 @@ - diff --git a/Plugins/Flow.Launcher.Plugin.Url/Main.cs b/Plugins/Flow.Launcher.Plugin.Url/Main.cs index 80425a8ff..03516636d 100644 --- a/Plugins/Flow.Launcher.Plugin.Url/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Url/Main.cs @@ -1,11 +1,10 @@ using System; using System.Collections.Generic; using System.Text.RegularExpressions; -using System.Windows.Controls; namespace Flow.Launcher.Plugin.Url { - public class Main : ISettingProvider,IPlugin, IPluginI18n + public class Main : IPlugin, IPluginI18n { //based on https://gist.github.com/dperini/729294 private const string urlPattern = "^" + @@ -43,7 +42,6 @@ namespace Flow.Launcher.Plugin.Url Regex reg = new Regex(urlPattern, RegexOptions.Compiled | RegexOptions.IgnoreCase); private PluginInitContext context; private Settings _settings; - public List Query(Query query) { @@ -82,12 +80,6 @@ namespace Flow.Launcher.Plugin.Url return new List(0); } - - public Control CreateSettingPanel() - { - return new SettingsControl(context.API,_settings); - } - public bool IsURL(string raw) { raw = raw.ToLower(); diff --git a/Plugins/Flow.Launcher.Plugin.Url/SettingsControl.xaml b/Plugins/Flow.Launcher.Plugin.Url/SettingsControl.xaml deleted file mode 100644 index 8ff7b5ab5..000000000 --- a/Plugins/Flow.Launcher.Plugin.Url/SettingsControl.xaml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - diff --git a/Plugins/Flow.Launcher.Plugin.Url/SettingsControl.xaml.cs b/Plugins/Flow.Launcher.Plugin.Url/SettingsControl.xaml.cs deleted file mode 100644 index f68d1bb2d..000000000 --- a/Plugins/Flow.Launcher.Plugin.Url/SettingsControl.xaml.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Windows.Controls; - -namespace Flow.Launcher.Plugin.Url -{ - public partial class SettingsControl : UserControl - { - private Settings _settings; - private IPublicAPI _flowlauncherAPI; - - public SettingsControl(IPublicAPI flowlauncherAPI,Settings settings) - { - InitializeComponent(); - _settings = settings; - _flowlauncherAPI = flowlauncherAPI; - - } - } -} From 6e84326f57c45cc44e6ab6a756244d277c9ef884 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Wed, 19 Feb 2025 23:43:17 +0800 Subject: [PATCH 003/298] Reassign margins --- .../Resources/Controls/InstalledPluginDisplayKeyword.xaml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Flow.Launcher/Resources/Controls/InstalledPluginDisplayKeyword.xaml b/Flow.Launcher/Resources/Controls/InstalledPluginDisplayKeyword.xaml index ff2f14c4b..a88b1a731 100644 --- a/Flow.Launcher/Resources/Controls/InstalledPluginDisplayKeyword.xaml +++ b/Flow.Launcher/Resources/Controls/InstalledPluginDisplayKeyword.xaml @@ -18,9 +18,9 @@ CornerRadius="0" Style="{DynamicResource SettingGroupBox}" Visibility="{Binding ActionKeywordsVisibility}"> - +  @@ -34,7 +34,6 @@ - +