fix: focus-window verifies foreground state instead of trusting AppActivate on Windows#1816
Conversation
|
Warning Review limit reached
Next review available in: 53 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (2)
📒 Files selected for processing (4)
📝 WalkthroughWalkthroughWindows focus command failures now distinguish context timeouts from script errors, while retaining stderr for non-timeout failures. Windows tests centralize assertions for foreground verification, escalation, restore-window capture, and unsupported script patterns. ChangesFocus error reporting
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…ppActivate on Windows The Windows focus scripts reported success whenever WScript.Shell AppActivate returned true, but the OS foreground lock rejects SetForegroundWindow from background processes, so `uloop focus-window` returned Success:true while Unity stayed behind other windows (measured with GetForegroundWindow on Windows 11). - Escalate activation: SW_RESTORE only when minimized, plain SetForegroundWindow, then AttachThreadInput to the foreground thread's input queue, then the transient Alt-key workaround - Verify with GetForegroundWindow that the foreground window belongs to the Unity PID after each stage; throw an actionable error (foreground lock, click Unity manually) when every stage fails - Remove the AppActivate fallback, the source of the false success - Map a FocusCommandTimeout kill (empty stderr) to an explanatory error instead of a bare "exit status 1", since activation calls can block on a stalled Editor message pump during domain reloads
bf17bfd to
902cf5d
Compare
4b18d53
into
feature/windows-v3-verification-integration
Problem
On Windows,
uloop focus-windowreturnedSuccess:true "Unity Editor window focused"even when the Unity Editor never came to the foreground (found in Phase 4 of the Windows v3 verification, measured withGetForegroundWindow).Root cause
The Windows foreground lock rejects
SetForegroundWindowcalls from background processes (the raw call returnsFalse, confirmed on Windows 11 26200). The focus scripts then fell back toWScript.Shell.AppActivate, which returnsTrueeven when the OS only flashes the taskbar button, so the CLI reported a false success.Fix
focus_unity_process.ps1/focus_unity_process_with_restore.ps1now use an escalation ladder of standard techniques, and never trust an API return value without verifying the result:ShowWindow(SW_RESTORE)only when the window is minimized (IsIconic), so a maximized Unity window is not shrunkSetForegroundWindowAttachThreadInputto the current foreground thread's input queue (plus the target thread),BringWindowToTop+SetForegroundWindow, then immediate detachkeybd_event VK_MENU) before a finalSetForegroundWindow, the documented workaround for the foreground lockAfter each stage the script verifies with
GetForegroundWindow+GetWindowThreadProcessIdthat the foreground window actually belongs to the Unity PID (polling up to 500 ms per stage). If every stage fails, the script throws an actionable error: Windows refused foreground activation, click the Unity window or its taskbar icon manually. TheAppActivatefallback — the source of the false success — is removed.Go side:
focus_windows.gonow maps aFocusCommandTimeoutkill to an explanatory error ("Editor may be busy, e.g. domain reload, retry once responsive") instead of a bareexit status 1. Activation calls can block on a stalled Editor message pump (observed once while Unity was mid domain reload), and a killed PowerShell writes nothing to stderr, so this was the only failure mode that produced an unexplained error.Verification (Windows 11, Unity 2022.3.62f3, HEAD-built project-runner)
Measured effect of each technique: plain
SetForegroundWindowreturnsFalseunder the foreground lock; theAttachThreadInputstage succeeds on this machine (Alt-key stage kept as a further fallback, not needed here).focus-window→ exit 0,Success:true,GetForegroundWindowstill Notepadfocus-window→ exit 0,Success:true,GetForegroundWindow= Unity PIDSuccess:false "No running Unity process found for this project", exit 1with_restore+ restore round-trip: Notepad → Unity → back to Notepad, previous handle emitted and restoredSuccess:falsewhile Unity was stalled in a domain reload (honest report instead of the previous false success)cli/common:go test ./...PASS,go vet/gofmtclean.cli/project-runner: one pre-existing Windows-incompatible test failure (TestRunControlPlayModeWithStateWaitPollsStatusAfterStaleInitialResponse, fails on the base commit too; PR-1 scope)