mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 11:48:06 +01:00
[Refactor]Use same improved BringToForeground across the solution (#28532)
* Use single BringToForeground across the solution * Close flyout manually * Try with sending input, if it fails try threads
This commit is contained in:
@@ -38,5 +38,67 @@ namespace ManagedCommon
|
|||||||
|
|
||||||
[DllImport("user32.dll")]
|
[DllImport("user32.dll")]
|
||||||
internal static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach);
|
internal static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach);
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
internal static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize);
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct INPUT
|
||||||
|
{
|
||||||
|
internal INPUTTYPE type;
|
||||||
|
internal InputUnion data;
|
||||||
|
|
||||||
|
internal static int Size
|
||||||
|
{
|
||||||
|
get { return Marshal.SizeOf(typeof(INPUT)); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
|
internal struct InputUnion
|
||||||
|
{
|
||||||
|
[FieldOffset(0)]
|
||||||
|
internal MOUSEINPUT mi;
|
||||||
|
[FieldOffset(0)]
|
||||||
|
internal KEYBDINPUT ki;
|
||||||
|
[FieldOffset(0)]
|
||||||
|
internal HARDWAREINPUT hi;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
internal struct MOUSEINPUT
|
||||||
|
{
|
||||||
|
internal int dx;
|
||||||
|
internal int dy;
|
||||||
|
internal int mouseData;
|
||||||
|
internal uint dwFlags;
|
||||||
|
internal uint time;
|
||||||
|
internal UIntPtr dwExtraInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
internal struct KEYBDINPUT
|
||||||
|
{
|
||||||
|
internal short wVk;
|
||||||
|
internal short wScan;
|
||||||
|
internal uint dwFlags;
|
||||||
|
internal int time;
|
||||||
|
internal UIntPtr dwExtraInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
internal struct HARDWAREINPUT
|
||||||
|
{
|
||||||
|
internal int uMsg;
|
||||||
|
internal short wParamL;
|
||||||
|
internal short wParamH;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal enum INPUTTYPE : uint
|
||||||
|
{
|
||||||
|
INPUT_MOUSE = 0,
|
||||||
|
INPUT_KEYBOARD = 1,
|
||||||
|
INPUT_HARDWARE = 2,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,20 +10,29 @@ namespace ManagedCommon
|
|||||||
{
|
{
|
||||||
public static void BringToForeground(IntPtr handle)
|
public static void BringToForeground(IntPtr handle)
|
||||||
{
|
{
|
||||||
|
NativeMethods.INPUT input = new NativeMethods.INPUT { type = NativeMethods.INPUTTYPE.INPUT_MOUSE, data = { } };
|
||||||
|
NativeMethods.INPUT[] inputs = new NativeMethods.INPUT[] { input };
|
||||||
|
_ = NativeMethods.SendInput(1, inputs, NativeMethods.INPUT.Size);
|
||||||
|
|
||||||
|
NativeMethods.SetForegroundWindow(handle);
|
||||||
|
|
||||||
var fgHandle = NativeMethods.GetForegroundWindow();
|
var fgHandle = NativeMethods.GetForegroundWindow();
|
||||||
|
|
||||||
var threadId1 = NativeMethods.GetWindowThreadProcessId(handle, System.IntPtr.Zero);
|
if (fgHandle != handle)
|
||||||
var threadId2 = NativeMethods.GetWindowThreadProcessId(fgHandle, System.IntPtr.Zero);
|
{
|
||||||
|
var threadId1 = NativeMethods.GetWindowThreadProcessId(handle, System.IntPtr.Zero);
|
||||||
|
var threadId2 = NativeMethods.GetWindowThreadProcessId(fgHandle, System.IntPtr.Zero);
|
||||||
|
|
||||||
if (threadId1 != threadId2)
|
if (threadId1 != threadId2)
|
||||||
{
|
{
|
||||||
NativeMethods.AttachThreadInput(threadId1, threadId2, true);
|
NativeMethods.AttachThreadInput(threadId1, threadId2, true);
|
||||||
NativeMethods.SetForegroundWindow(handle);
|
NativeMethods.SetForegroundWindow(handle);
|
||||||
NativeMethods.AttachThreadInput(threadId1, threadId2, false);
|
NativeMethods.AttachThreadInput(threadId1, threadId2, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NativeMethods.SetForegroundWindow(handle);
|
NativeMethods.SetForegroundWindow(handle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
// See the LICENSE file in the project root for more information.
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
using Hosts.Helpers;
|
using Hosts.Helpers;
|
||||||
|
using ManagedCommon;
|
||||||
using Microsoft.UI.Xaml;
|
using Microsoft.UI.Xaml;
|
||||||
using Microsoft.UI.Xaml.Media;
|
using Microsoft.UI.Xaml.Media;
|
||||||
using WinUIEx;
|
using WinUIEx;
|
||||||
@@ -25,7 +26,7 @@ namespace Hosts
|
|||||||
AppTitleTextBlock.Text = title;
|
AppTitleTextBlock.Text = title;
|
||||||
|
|
||||||
var handle = this.GetWindowHandle();
|
var handle = this.GetWindowHandle();
|
||||||
ManagedCommon.WindowHelpers.BringToForeground(handle);
|
WindowHelpers.BringToForeground(handle);
|
||||||
|
|
||||||
Activated += MainWindow_Activated;
|
Activated += MainWindow_Activated;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ using ImageResizer.Properties;
|
|||||||
using ImageResizer.Utilities;
|
using ImageResizer.Utilities;
|
||||||
using ImageResizer.ViewModels;
|
using ImageResizer.ViewModels;
|
||||||
using ImageResizer.Views;
|
using ImageResizer.Views;
|
||||||
|
using ManagedCommon;
|
||||||
|
|
||||||
namespace ImageResizer
|
namespace ImageResizer
|
||||||
{
|
{
|
||||||
@@ -41,15 +42,7 @@ namespace ImageResizer
|
|||||||
mainWindow.Show();
|
mainWindow.Show();
|
||||||
|
|
||||||
// Temporary workaround for issue #1273
|
// Temporary workaround for issue #1273
|
||||||
BecomeForegroundWindow(new System.Windows.Interop.WindowInteropHelper(mainWindow).Handle);
|
WindowHelpers.BringToForeground(new System.Windows.Interop.WindowInteropHelper(mainWindow).Handle);
|
||||||
}
|
|
||||||
|
|
||||||
private static void BecomeForegroundWindow(IntPtr hWnd)
|
|
||||||
{
|
|
||||||
NativeMethods.INPUT input = new NativeMethods.INPUT { type = NativeMethods.INPUTTYPE.INPUT_MOUSE, data = { } };
|
|
||||||
NativeMethods.INPUT[] inputs = new NativeMethods.INPUT[] { input };
|
|
||||||
_ = NativeMethods.SendInput(1, inputs, NativeMethods.INPUT.Size);
|
|
||||||
NativeMethods.SetForegroundWindow(hWnd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
|||||||
@@ -15,69 +15,7 @@ namespace ImageResizer.Utilities
|
|||||||
[DllImport("user32.dll")]
|
[DllImport("user32.dll")]
|
||||||
internal static extern bool SetForegroundWindow(IntPtr hWnd);
|
internal static extern bool SetForegroundWindow(IntPtr hWnd);
|
||||||
|
|
||||||
[DllImport("user32.dll")]
|
|
||||||
internal static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize);
|
|
||||||
|
|
||||||
[DllImport("user32.dll", SetLastError = true)]
|
[DllImport("user32.dll", SetLastError = true)]
|
||||||
internal static extern bool SetProcessDPIAware();
|
internal static extern bool SetProcessDPIAware();
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
|
||||||
public struct INPUT
|
|
||||||
{
|
|
||||||
internal INPUTTYPE type;
|
|
||||||
internal InputUnion data;
|
|
||||||
|
|
||||||
internal static int Size
|
|
||||||
{
|
|
||||||
get { return Marshal.SizeOf(typeof(INPUT)); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
|
||||||
internal struct InputUnion
|
|
||||||
{
|
|
||||||
[FieldOffset(0)]
|
|
||||||
internal MOUSEINPUT mi;
|
|
||||||
[FieldOffset(0)]
|
|
||||||
internal KEYBDINPUT ki;
|
|
||||||
[FieldOffset(0)]
|
|
||||||
internal HARDWAREINPUT hi;
|
|
||||||
}
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
|
||||||
internal struct MOUSEINPUT
|
|
||||||
{
|
|
||||||
internal int dx;
|
|
||||||
internal int dy;
|
|
||||||
internal int mouseData;
|
|
||||||
internal uint dwFlags;
|
|
||||||
internal uint time;
|
|
||||||
internal UIntPtr dwExtraInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
|
||||||
internal struct KEYBDINPUT
|
|
||||||
{
|
|
||||||
internal short wVk;
|
|
||||||
internal short wScan;
|
|
||||||
internal uint dwFlags;
|
|
||||||
internal int time;
|
|
||||||
internal UIntPtr dwExtraInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
|
||||||
internal struct HARDWAREINPUT
|
|
||||||
{
|
|
||||||
internal int uMsg;
|
|
||||||
internal short wParamL;
|
|
||||||
internal short wParamH;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal enum INPUTTYPE : uint
|
|
||||||
{
|
|
||||||
INPUT_MOUSE = 0,
|
|
||||||
INPUT_KEYBOARD = 1,
|
|
||||||
INPUT_HARDWARE = 2,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,19 +22,6 @@ namespace Peek.UI.Extensions
|
|||||||
return hwnd.GetMonitorScale();
|
return hwnd.GetMonitorScale();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void BringToForeground(this Window window)
|
|
||||||
{
|
|
||||||
// Ability to be able to set the Window to the Foreground is very limited. A current workaround is simulating mouse input before bringing to the foreground.
|
|
||||||
var windowHandle = window.GetWindowHandle();
|
|
||||||
Windows.Win32.UI.Input.KeyboardAndMouse.INPUT input = new Windows.Win32.UI.Input.KeyboardAndMouse.INPUT { type = Windows.Win32.UI.Input.KeyboardAndMouse.INPUT_TYPE.INPUT_MOUSE, Anonymous = { } };
|
|
||||||
Windows.Win32.UI.Input.KeyboardAndMouse.INPUT[] inputs = new Windows.Win32.UI.Input.KeyboardAndMouse.INPUT[] { input };
|
|
||||||
_ = PInvoke.SendInput(inputs.AsSpan<Windows.Win32.UI.Input.KeyboardAndMouse.INPUT>(), Marshal.SizeOf(typeof(Windows.Win32.UI.Input.KeyboardAndMouse.INPUT)));
|
|
||||||
if (PInvoke.SetForegroundWindow(new HWND(windowHandle)) == 0)
|
|
||||||
{
|
|
||||||
Logger.LogWarning("Couldn't set the Peek window as the foreground window.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void CenterOnMonitor(this Window window, HWND hwndDesktop, double? width = null, double? height = null)
|
internal static void CenterOnMonitor(this Window window, HWND hwndDesktop, double? width = null, double? height = null)
|
||||||
{
|
{
|
||||||
var hwndToCenter = new HWND(window.GetWindowHandle());
|
var hwndToCenter = new HWND(window.GetWindowHandle());
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ GetDpiForWindow
|
|||||||
GetForegroundWindow
|
GetForegroundWindow
|
||||||
SetForegroundWindow
|
SetForegroundWindow
|
||||||
SetActiveWindow
|
SetActiveWindow
|
||||||
SendInput
|
|
||||||
GetWindowThreadProcessId
|
GetWindowThreadProcessId
|
||||||
GetCurrentThreadId
|
GetCurrentThreadId
|
||||||
AttachThreadInput
|
AttachThreadInput
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ namespace Peek.UI
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.Show();
|
this.Show();
|
||||||
this.BringToForeground();
|
WindowHelpers.BringToForeground(this.GetWindowHandle());
|
||||||
}
|
}
|
||||||
|
|
||||||
private Size GetMonitorMaxContentSize(Size monitorSize, double scaling)
|
private Size GetMonitorMaxContentSize(Size monitorSize, double scaling)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using ManagedCommon;
|
||||||
using Microsoft.UI;
|
using Microsoft.UI;
|
||||||
using Microsoft.UI.Xaml;
|
using Microsoft.UI.Xaml;
|
||||||
using Microsoft.UI.Xaml.Controls;
|
using Microsoft.UI.Xaml.Controls;
|
||||||
@@ -98,7 +99,7 @@ namespace RegistryPreview
|
|||||||
UpdateWindowTitle(resourceLoader.GetString("FileNotFound"));
|
UpdateWindowTitle(resourceLoader.GetString("FileNotFound"));
|
||||||
}
|
}
|
||||||
|
|
||||||
ManagedCommon.WindowHelpers.BringToForeground(windowHandle);
|
WindowHelpers.BringToForeground(windowHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MainWindow_Activated(object sender, WindowActivatedEventArgs args)
|
private void MainWindow_Activated(object sender, WindowActivatedEventArgs args)
|
||||||
|
|||||||
@@ -45,13 +45,5 @@ namespace Microsoft.PowerToys.Settings.UI.Helpers
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void BecomeForegroundWindow(IntPtr hWnd)
|
|
||||||
{
|
|
||||||
NativeKeyboardHelper.INPUT input = new NativeKeyboardHelper.INPUT { type = NativeKeyboardHelper.INPUTTYPE.INPUT_MOUSE, data = { } };
|
|
||||||
NativeKeyboardHelper.INPUT[] inputs = new NativeKeyboardHelper.INPUT[] { input };
|
|
||||||
_ = NativeMethods.SendInput(1, inputs, NativeKeyboardHelper.INPUT.Size);
|
|
||||||
NativeMethods.SetForegroundWindow(hWnd);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ namespace Microsoft.PowerToys.Settings.UI
|
|||||||
|
|
||||||
// https://github.com/microsoft/microsoft-ui-xaml/issues/7595 - Activate doesn't bring window to the foreground
|
// https://github.com/microsoft/microsoft-ui-xaml/issues/7595 - Activate doesn't bring window to the foreground
|
||||||
// Need to call SetForegroundWindow to actually gain focus.
|
// Need to call SetForegroundWindow to actually gain focus.
|
||||||
Utils.BecomeForegroundWindow(settingsWindow.GetWindowHandle());
|
WindowHelpers.BringToForeground(settingsWindow.GetWindowHandle());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -33,6 +33,10 @@ namespace Microsoft.PowerToys.Settings.UI.Flyout
|
|||||||
{
|
{
|
||||||
FlyoutMenuButton selectedModuleBtn = sender as FlyoutMenuButton;
|
FlyoutMenuButton selectedModuleBtn = sender as FlyoutMenuButton;
|
||||||
bool moduleRun = true;
|
bool moduleRun = true;
|
||||||
|
|
||||||
|
// Closing manually the flyout to workaround focus gain problems
|
||||||
|
App.GetFlyoutWindow()?.Hide();
|
||||||
|
|
||||||
switch ((string)selectedModuleBtn.Tag)
|
switch ((string)selectedModuleBtn.Tag)
|
||||||
{
|
{
|
||||||
case "ColorPicker": // Launch ColorPicker
|
case "ColorPicker": // Launch ColorPicker
|
||||||
|
|||||||
@@ -205,7 +205,7 @@ namespace Microsoft.PowerToys.Settings.UI
|
|||||||
|
|
||||||
// https://github.com/microsoft/microsoft-ui-xaml/issues/7595 - Activate doesn't bring window to the foreground
|
// https://github.com/microsoft/microsoft-ui-xaml/issues/7595 - Activate doesn't bring window to the foreground
|
||||||
// Need to call SetForegroundWindow to actually gain focus.
|
// Need to call SetForegroundWindow to actually gain focus.
|
||||||
Utils.BecomeForegroundWindow(flyout.GetWindowHandle());
|
WindowHelpers.BringToForeground(flyout.GetWindowHandle());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user