fix(input): inject a no-op input event so force-foreground actually works

Follow-up to the AttachThreadInput change: verified against an isolated repro
(a foreground-stealing window + the helper spawned exactly like the app) that
AttachThreadInput + clearing the foreground-lock timeout was NOT sufficient on
this Windows build - SetForegroundWindow still returned false and Genshin stayed
in the background.

The missing condition is "the calling process received the last input event".
Injecting a benign no-op input (a 0,0 relative mouse move, no cursor movement, no
menu-mnemonic side effect) right before SetForegroundWindow satisfies it. With the
nudge the repro now returns focused:true / setForegroundResult:true from a
background process while another app holds the foreground - the exact auto-scan
start scenario. Applied to both the C# sidecar and the PowerShell fallback.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
AzuTear
2026-07-06 16:13:25 +02:00
parent c8ae0dd7bf
commit b8309af377
2 changed files with 18 additions and 0 deletions
+15
View File
@@ -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<Native.INPUT>());
}
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;