mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 11:48:06 +01:00
update
Signed-off-by: Shawn Yuan (from Dev Box) <shuaiyuan@microsoft.com>
This commit is contained in:
@@ -43,6 +43,9 @@ public sealed partial class MainWindow : WindowEx, IDisposable
|
||||
private MemoryMappedFile? _positionMap;
|
||||
private MemoryMappedViewAccessor? _positionView;
|
||||
private PointInt32? _lastRequestedPosition;
|
||||
private bool _isVisible;
|
||||
private IntPtr _mouseHook;
|
||||
private LowLevelMouseProc? _mouseHookDelegate;
|
||||
|
||||
private const int DefaultWidth = 320;
|
||||
private const int DefaultHeight = 480;
|
||||
@@ -118,6 +121,9 @@ public sealed partial class MainWindow : WindowEx, IDisposable
|
||||
{
|
||||
_appWindow.Hide();
|
||||
}
|
||||
|
||||
_isVisible = false;
|
||||
RemoveGlobalMouseHook();
|
||||
}
|
||||
|
||||
internal void RequestHide()
|
||||
@@ -231,6 +237,8 @@ public sealed partial class MainWindow : WindowEx, IDisposable
|
||||
_hasSeenInteractiveActivation = true;
|
||||
_initialActivationHandled = true;
|
||||
Activate();
|
||||
_isVisible = true;
|
||||
EnsureGlobalMouseHook();
|
||||
}
|
||||
|
||||
private void OnActivated(object sender, WindowActivatedEventArgs args)
|
||||
@@ -363,6 +371,7 @@ public sealed partial class MainWindow : WindowEx, IDisposable
|
||||
UncloakWindow();
|
||||
}
|
||||
|
||||
RemoveGlobalMouseHook();
|
||||
DisposePositionResources();
|
||||
|
||||
_coordinator.Dispose();
|
||||
@@ -404,6 +413,21 @@ public sealed partial class MainWindow : WindowEx, IDisposable
|
||||
[DllImport("user32.dll", EntryPoint = "GetMonitorInfoW", SetLastError = true)]
|
||||
private static extern bool GetMonitorInfoNative(IntPtr hMonitor, ref MonitorInfo lpmi);
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "SetWindowsHookExW", SetLastError = true)]
|
||||
private static extern IntPtr SetWindowsHookExNative(int idHook, LowLevelMouseProc lpfn, IntPtr hMod, uint dwThreadId);
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "UnhookWindowsHookEx", SetLastError = true)]
|
||||
private static extern bool UnhookWindowsHookExNative(IntPtr hhk);
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "CallNextHookEx", SetLastError = true)]
|
||||
private static extern IntPtr CallNextHookExNative(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
[DllImport("kernel32.dll", EntryPoint = "GetModuleHandleW", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
private static extern IntPtr GetModuleHandleNative([MarshalAs(UnmanagedType.LPWStr)] string? lpModuleName);
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "GetWindowRect", SetLastError = true)]
|
||||
private static extern bool GetWindowRectNative(IntPtr hWnd, out Rect rect);
|
||||
|
||||
private static void BringToForeground(IntPtr hwnd)
|
||||
{
|
||||
if (hwnd == IntPtr.Zero)
|
||||
@@ -436,6 +460,70 @@ public sealed partial class MainWindow : WindowEx, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
private void EnsureGlobalMouseHook()
|
||||
{
|
||||
if (_mouseHook != IntPtr.Zero)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_mouseHookDelegate ??= LowLevelMouseHookCallback;
|
||||
var moduleHandle = GetModuleHandleNative(null);
|
||||
_mouseHook = SetWindowsHookExNative(WhMouseLl, _mouseHookDelegate, moduleHandle, 0);
|
||||
}
|
||||
|
||||
private void RemoveGlobalMouseHook()
|
||||
{
|
||||
if (_mouseHook == IntPtr.Zero)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UnhookWindowsHookExNative(_mouseHook);
|
||||
_mouseHook = IntPtr.Zero;
|
||||
}
|
||||
|
||||
private IntPtr LowLevelMouseHookCallback(int nCode, IntPtr wParam, IntPtr lParam)
|
||||
{
|
||||
if (nCode >= 0 && _isVisible && lParam != IntPtr.Zero && IsMouseButtonDownMessage(wParam))
|
||||
{
|
||||
var data = Marshal.PtrToStructure<LowLevelMouseInput>(lParam);
|
||||
if (!IsPointInsideWindow(data.Point))
|
||||
{
|
||||
_dispatcherQueue.TryEnqueue(() =>
|
||||
{
|
||||
if (_isVisible)
|
||||
{
|
||||
HideWindow();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return CallNextHookExNative(_mouseHook, nCode, wParam, lParam);
|
||||
}
|
||||
|
||||
private static bool IsMouseButtonDownMessage(IntPtr wParam)
|
||||
{
|
||||
var message = wParam.ToInt32();
|
||||
return message == WmLbuttondown || message == WmRbuttondown || message == WmMbuttondown || message == WmXbuttondown;
|
||||
}
|
||||
|
||||
private bool IsPointInsideWindow(NativePoint point)
|
||||
{
|
||||
if (_hwnd == IntPtr.Zero)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GetWindowRectNative(_hwnd, out var rect))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return point.X >= rect.Left && point.X <= rect.Right && point.Y >= rect.Top && point.Y <= rect.Bottom;
|
||||
}
|
||||
|
||||
private void EnsureListenerInfrastructure()
|
||||
{
|
||||
_listenerShutdownEvent ??= new ManualResetEventSlim(false);
|
||||
@@ -754,7 +842,32 @@ public sealed partial class MainWindow : WindowEx, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
private const int WhMouseLl = 14;
|
||||
private const int WmLbuttondown = 0x0201;
|
||||
private const int WmRbuttondown = 0x0204;
|
||||
private const int WmMbuttondown = 0x0207;
|
||||
private const int WmXbuttondown = 0x020B;
|
||||
|
||||
private delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
private struct Rect
|
||||
{
|
||||
public int Left;
|
||||
public int Top;
|
||||
public int Right;
|
||||
public int Bottom;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct LowLevelMouseInput
|
||||
{
|
||||
public NativePoint Point;
|
||||
public int MouseData;
|
||||
public int Flags;
|
||||
public int Time;
|
||||
public IntPtr DwExtraInfo;
|
||||
}
|
||||
|
||||
private struct NativePoint
|
||||
{
|
||||
public int X;
|
||||
@@ -769,13 +882,4 @@ public sealed partial class MainWindow : WindowEx, IDisposable
|
||||
public Rect RcWork;
|
||||
public uint DwFlags;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct Rect
|
||||
{
|
||||
public int Left;
|
||||
public int Top;
|
||||
public int Right;
|
||||
public int Bottom;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user