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