---
title: "Building Windows That Know to Get Out of the Way"
canonical: https://dxdev.com/blog/2026-09-24_agent-window-placement-behind-focus/
datePublished: 2026-09-24
---
Six agent windows opened on top of the one I was typing in, and every one of them got its own taskbar button. That was the state of the cockpit, the local web app that hosts our agent sessions, by the time I decided to fix it.

Each spawned session opens its own browser window. With three or four running, each new window landed on top of whatever I was focused on and took my keystrokes with it. If you spawn agents while you work, you learn to type carefully.

## Placing new windows behind the one I'm using

The fix was one rule for slot placement. When the cockpit spawns a window, it first finds the window I currently have maximized and in focus. It then puts the new window behind that one. Agents get their slot, I keep my keyboard, and I find them when I alt-tab.

The second half was a guard on spawn-open. If window creation failed, the spawn call used to sit there and report nothing. That is worse than a crash, because a session you believe exists is not running and nothing tells you. Now spawn-open fails loudly instead of hanging. A follow-on commit tightened that path.

## Why every window wanted its own taskbar button

The same night I found the cause. Chrome builds a window's identity from the launch URL's path, and our session id sat in that path. Every session was therefore a different app as far as Windows was concerned. I moved the id into a query string. Now `/session/abc123` becomes `/session?id=abc123`, every session window shares one identity, and they collapse into a single button. I shipped and deployed both sides.

Looking into that turned up a pre-existing bug in window lookup, which I filed instead of folding into the same change.

## The session that died mid-build

The agent that built the placement logic was itself running inside the cockpit. It committed the work, and then the cockpit restarted at 5:42 PM to pick up other changes, and the session went down with it. It had been running for 4 hours 2 minutes. The commit survived, but the session did not. It never got to close its own manifest, so the hub closed it for me afterward.

Three other sessions died in the same restart. One of them had edited two test files and started a baseline run. Another had finished its code and left it uncommitted. The hub had to finish that one, run the suite (5,353 passed) and commit it.

So the feature that keeps agent windows from stealing focus was built by an agent that lost its own window to a restart. Nothing was lost, because the commits were already on disk. Anything not committed depended on another session picking it up, and that only worked because the hub tracks who owns what.

## Restarting a host that owns its agents

If your agent host runs its agents as children, restarting the host kills them. Commit before you restart, and record the work somewhere other than the session's own memory. Placement behind focus, one shared window identity, and a spawn that cannot hang silently are all small changes. Together they mean I can run four sessions and keep typing in the fifth window without them getting in my way.
