player: active foreground wait replaces fixed 600ms sleep (#14)
BringSutToForeground() now polls GetForegroundWindow() == SUT hwnd at 25ms intervals up to 2s, followed by a 100ms tail settle, instead of the brittle fixed 600ms sleep. First-attempt replay of box-v6.yaml is now reliable (previously dropped the opening "BOX" keystrokes on a cold start). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -212,21 +212,34 @@ public sealed class UiaPlayerHost : IPlayerHost, IDisposable
|
||||
/// was launched from a shell that still has focus when the first Type/Hotkey
|
||||
/// step fires.
|
||||
/// </summary>
|
||||
[System.Runtime.InteropServices.DllImport("user32.dll")]
|
||||
private static extern IntPtr GetForegroundWindow();
|
||||
|
||||
public void BringSutToForeground()
|
||||
{
|
||||
try
|
||||
{
|
||||
var w = _app?.GetMainWindow(_automation, TimeSpan.FromSeconds(5));
|
||||
if (w is null) return;
|
||||
var targetHwnd = w.Properties.NativeWindowHandle.ValueOrDefault;
|
||||
try { w.SetForeground(); } catch { /* best-effort */ }
|
||||
try { w.Focus(); } catch { /* best-effort */ }
|
||||
// Small settle so the OS-level focus switch takes effect before
|
||||
// the first SendInput. 150ms is enough in practice on Win10.
|
||||
// Increased from 150→600ms because FlaUI Keyboard.Type drops the
|
||||
// first couple of characters if SendInput fires before the OS
|
||||
// finishes the focus transition (observed: "BOX" lost on first
|
||||
// step, "10" succeeded later once the app had settled).
|
||||
System.Threading.Thread.Sleep(600);
|
||||
|
||||
// Issue #14 follow-up: active wait instead of fixed 600ms sleep.
|
||||
// Poll until the OS reports the SUT as the foreground window, up
|
||||
// to 2s. Previously a 600ms fixed sleep was threshold-sensitive
|
||||
// and caused the first "BOX" keystroke to get dropped on a cold
|
||||
// first run.
|
||||
var deadline = DateTime.UtcNow.AddSeconds(2);
|
||||
while (DateTime.UtcNow < deadline)
|
||||
{
|
||||
if (targetHwnd != IntPtr.Zero && GetForegroundWindow() == targetHwnd)
|
||||
break;
|
||||
System.Threading.Thread.Sleep(25);
|
||||
}
|
||||
// Tiny additional settle for the OS keyboard-focus IPC to finish
|
||||
// after the foreground transition is observed.
|
||||
System.Threading.Thread.Sleep(100);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user