fix(android): open the macOS emulator window behind the focused app

Merged
TH
1d ago
+207-250

Summary

On macOS, a GUI Android emulator launch (boot --platform android --device <avd>, or open booting a stopped AVD) took focus from the app you were using. The emulator has no flag to stop this; -qt-hide-window hides the window, and Qt's background-only mode removes the Dock icon and Cmd-Tab entry. The launch host now reads the frontmost app with lsappinfo before spawning the emulator, then starts a JXA watcher for the remaining startup budget. When the emulator becomes frontmost, the watcher reactivates the previous app once and exits. The window lands directly below that app, which matches how iOS opens Simulator with open -g. Headless and non-macOS launches are unchanged. The androidEmulator.launch port is async now and receives the boot budget.

The second commit removes ensureAndroidEmulatorBooted. Production boots emulators only through readiness/runtime.ts and the host launch port, so this other launch path had no caller outside its own tests.

Validation

Tested head 3ad7668d79, macOS 26.6.2, emulator 36.2.12, AVD Pixel_9_Pro_XL_API_37. Frontmost app polled every 20 ms during agent-device boot:

base (emulator launched directly)head
1s front: qemu-system-aarch64, focus stays stolen3s front: qemu-system-aarch64, then back to Claude within the same second; window order: Claude, then qemu-system-aarch64

No watcher process was left after the run.

  • pnpm check:affected --run: passed on 8e1b826052. CI passed in full on d5562c845b, and 8e1b826052 only changes docs wording. The later commits only make the frontmost-app read best-effort and change docs wording, so the live run on 3ad7668d79 still covers the success path.
  • Unit tests cover the frontmost-pid capture, an unreadable or failing frontmost-app read, headless and non-darwin launches, and passing the boot budget from readiness. The budget test fails when the passed value is changed.

Remaining risk: the emulator holds focus for up to ~50 ms (one watcher poll).