mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-01-18 14:41:21 +08:00
[Run][WindowWalker]Improve EnumWindows synchronization (#27490)
This commit is contained in:
parent
082c312325
commit
e02ceaa8d0
@ -6,6 +6,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using Wox.Plugin.Common.Win32;
|
||||
|
||||
namespace Microsoft.Plugin.WindowWalker.Components
|
||||
@ -15,6 +17,11 @@ namespace Microsoft.Plugin.WindowWalker.Components
|
||||
/// </summary>
|
||||
internal class OpenWindows
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to enforce single execution of EnumWindows
|
||||
/// </summary>
|
||||
private static readonly object _enumWindowsLock = new();
|
||||
|
||||
/// <summary>
|
||||
/// PowerLauncher main executable
|
||||
/// </summary>
|
||||
@ -33,10 +40,7 @@ namespace Microsoft.Plugin.WindowWalker.Components
|
||||
/// <summary>
|
||||
/// Gets the list of all open windows
|
||||
/// </summary>
|
||||
internal List<Window> Windows
|
||||
{
|
||||
get { return new List<Window>(windows); }
|
||||
}
|
||||
internal List<Window> Windows => windows;
|
||||
|
||||
/// <summary>
|
||||
/// Gets an instance property of this class that makes sure that
|
||||
@ -68,11 +72,26 @@ namespace Microsoft.Plugin.WindowWalker.Components
|
||||
/// <summary>
|
||||
/// Updates the list of open windows
|
||||
/// </summary>
|
||||
internal void UpdateOpenWindowsList()
|
||||
internal void UpdateOpenWindowsList(CancellationToken cancellationToken)
|
||||
{
|
||||
windows.Clear();
|
||||
EnumWindowsProc callbackptr = new EnumWindowsProc(WindowEnumerationCallBack);
|
||||
_ = NativeMethods.EnumWindows(callbackptr, 0);
|
||||
var tokenHandle = GCHandle.Alloc(cancellationToken);
|
||||
try
|
||||
{
|
||||
var tokenHandleParam = GCHandle.ToIntPtr(tokenHandle);
|
||||
lock (_enumWindowsLock)
|
||||
{
|
||||
windows.Clear();
|
||||
EnumWindowsProc callbackptr = new EnumWindowsProc(WindowEnumerationCallBack);
|
||||
_ = NativeMethods.EnumWindows(callbackptr, tokenHandleParam);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (tokenHandle.IsAllocated)
|
||||
{
|
||||
tokenHandle.Free();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -84,6 +103,14 @@ namespace Microsoft.Plugin.WindowWalker.Components
|
||||
/// <returns>true to make sure to continue enumeration</returns>
|
||||
internal bool WindowEnumerationCallBack(IntPtr hwnd, IntPtr lParam)
|
||||
{
|
||||
var tokenHandle = GCHandle.FromIntPtr(lParam);
|
||||
var cancellationToken = (CancellationToken)tokenHandle.Target;
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
// Stop enumeration
|
||||
return false;
|
||||
}
|
||||
|
||||
Window newWindow = new Window(hwnd);
|
||||
|
||||
if (newWindow.IsWindow && newWindow.Visible && newWindow.IsOwner &&
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Windows.Controls;
|
||||
using ManagedCommon;
|
||||
using Microsoft.Plugin.WindowWalker.Components;
|
||||
@ -13,8 +14,11 @@ using Wox.Plugin.Common.VirtualDesktop.Helper;
|
||||
|
||||
namespace Microsoft.Plugin.WindowWalker
|
||||
{
|
||||
public class Main : IPlugin, IPluginI18n, ISettingProvider, IContextMenu
|
||||
public class Main : IPlugin, IPluginI18n, ISettingProvider, IContextMenu, IDisposable
|
||||
{
|
||||
private CancellationTokenSource _cancellationTokenSource = new();
|
||||
private bool _disposed;
|
||||
|
||||
private string IconPath { get; set; }
|
||||
|
||||
private string InfoIconPath { get; set; }
|
||||
@ -27,11 +31,6 @@ namespace Microsoft.Plugin.WindowWalker
|
||||
|
||||
internal static readonly VirtualDesktopHelper VirtualDesktopHelperInstance = new VirtualDesktopHelper();
|
||||
|
||||
static Main()
|
||||
{
|
||||
OpenWindows.Instance.UpdateOpenWindowsList();
|
||||
}
|
||||
|
||||
public List<Result> Query(Query query)
|
||||
{
|
||||
if (query == null)
|
||||
@ -39,8 +38,12 @@ namespace Microsoft.Plugin.WindowWalker
|
||||
throw new ArgumentNullException(nameof(query));
|
||||
}
|
||||
|
||||
_cancellationTokenSource?.Cancel();
|
||||
_cancellationTokenSource?.Dispose();
|
||||
_cancellationTokenSource = new CancellationTokenSource();
|
||||
|
||||
VirtualDesktopHelperInstance.UpdateDesktopList();
|
||||
OpenWindows.Instance.UpdateOpenWindowsList();
|
||||
OpenWindows.Instance.UpdateOpenWindowsList(_cancellationTokenSource.Token);
|
||||
SearchController.Instance.UpdateSearchText(query.Search);
|
||||
List<SearchResult> searchControllerResults = SearchController.Instance.SearchMatches;
|
||||
|
||||
@ -103,5 +106,23 @@ namespace Microsoft.Plugin.WindowWalker
|
||||
{
|
||||
WindowWalkerSettings.Instance.UpdateSettings(settings);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(disposing: true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!_disposed)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_cancellationTokenSource?.Dispose();
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ namespace Wox.Plugin.Common.Win32
|
||||
public static class NativeMethods
|
||||
{
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||
public static extern int EnumWindows(EnumWindowsProc callPtr, int lPar);
|
||||
public static extern int EnumWindows(EnumWindowsProc callPtr, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern IntPtr GetWindow(IntPtr hWnd, GetWindowCmd uCmd);
|
||||
|
Loading…
Reference in New Issue
Block a user