diff --git a/electron/services/inputHelper.ts b/electron/services/inputHelper.ts index e3e6f41..68c87b0 100644 --- a/electron/services/inputHelper.ts +++ b/electron/services/inputHelper.ts @@ -216,6 +216,9 @@ function Force-Foreground { if ($foreground -ne 0 -and $foreground -ne $current -and $foreground -ne $target) { $attachedForeground = [Native.InputHelper]::AttachThreadInput($current, $foreground, $true) } $timeoutRead = [Native.InputHelper]::SystemParametersInfoGet(0x2000, 0, [ref]$oldTimeout, 0) [Native.InputHelper]::SystemParametersInfoSet(0x2001, 0, [IntPtr]::Zero, 0x0002) | Out-Null + # Inject a no-op input (0,0 mouse move) so this process is the last input + # source, which Windows requires before it will honor a foreground change. + Send-MouseInput -flags 0x0001 | Out-Null [Native.InputHelper]::ShowWindowAsync($hwnd, 9) | Out-Null [Native.InputHelper]::BringWindowToTop($hwnd) | Out-Null return [Native.InputHelper]::SetForegroundWindow($hwnd) diff --git a/native/input-helper/Program.cs b/native/input-helper/Program.cs index e237f7f..b469339 100644 --- a/native/input-helper/Program.cs +++ b/native/input-helper/Program.cs @@ -316,6 +316,12 @@ internal static class Program timeoutRead = Native.SystemParametersInfo(Native.SPI_GETFOREGROUNDLOCKTIMEOUT, 0, ref oldTimeout, 0); Native.SystemParametersInfo(Native.SPI_SETFOREGROUNDLOCKTIMEOUT, 0, IntPtr.Zero, Native.SPIF_SENDCHANGE); + // Inject a no-op input (0,0 relative mouse move) so this process counts + // as the last input source - one of the conditions Windows requires to + // allow a foreground change. This is what the removed ALT tap did, but + // without the menu-mnemonic side effect. + NudgeInput(); + Native.ShowWindowAsync(hwnd, 9); // SW_RESTORE Native.BringWindowToTop(hwnd); var ok = Native.SetForegroundWindow(hwnd); @@ -390,6 +396,14 @@ internal static class Program return principal.IsInRole(WindowsBuiltInRole.Administrator); } + private static void NudgeInput() + { + var move = new Native.INPUT[1]; + move[0].type = 0; // INPUT_MOUSE + move[0].mi.dwFlags = Native.MOUSEEVENTF_MOVE; // dx=dy=0 -> no cursor movement + Native.SendInput(1, move, Marshal.SizeOf()); + } + private static uint SendMouseClickBatch() { var inputs = new Native.INPUT[2]; @@ -427,6 +441,7 @@ internal static class Program internal static class Native { + public const uint MOUSEEVENTF_MOVE = 0x0001; public const uint MOUSEEVENTF_LEFTDOWN = 0x0002; public const uint MOUSEEVENTF_LEFTUP = 0x0004; public const uint MOUSEEVENTF_WHEEL = 0x0800;