KiCad - the KiCad Bridge
Public Made by Adomby adom
Drive your own KiCad from an AI, in the background: open every editor, read the whole board as data (the EDA Bridge Standard board model), stack-up, part heights, netlists, place, route, pour, DRC and exports.
KiCad windows grab the foreground on every open and are only bounced afterwards: the user sees every one (30 in one battery)
Parked (kicad-lane, 2026-10-29): KiCad raises its own frames when they open. The bridge already starts KiCad with SW_SHOWNOACTIVATE. The only counter, the background guard (#114, closed into this), is off by default because it fought the user. See the latest comment for today's numbers and what a guard needs before it comes back.
What John saw (2026-09-21)
While the verb battery ran on AdomLapper, KiCad kept coming to the front of a YouTube video. John: "why do you always have to push kicad to the foreground? its really disrupting", and "make your kicad-bridge code such that kicad stays in the background and only in the worst most desperate cases, foreground it".
What the bridge's own log says
kicad_state {includeImages:false}.focusEvents after one battery:
| Box | Foreground grabs that were bounced |
|---|---|
| AdomLapper (John watching a video) | 30 |
| arav-rog | 40 |
| winvm (nobody at the console) | 16 after a handful of verbs |
Every KiCad window kind does it: PCB Editor, Symbol Editor, Footprint Editor, 3D Viewer, Schematic Editor, and the progress dialogs (Load PCB, Loading, Fill All Zones). Both new processes and second frames inside a process that is already running.
Why nobody caught it
The design is REACTIVE: spawn with SW_SHOWNOACTIVATE, then a WinEvent hook and a 120 ms sentinel bounce a window once after it reaches the foreground. The bounce lands within milliseconds, so the verb battery, which looks at the foreground window one second after each verb, reported "zero steals" on every box for weeks. The user still sees every grab: a flash over their window, keyboard focus gone for a moment, a fullscreen video interrupted.
Fixed today in the runner: it now counts every steal event in the focus log for the run and the run is RED while that count is above zero.
What does not explain it
HKCU\Control Panel\Desktop\ForegroundLockTimeout is 0 on AdomLapper, ConfRoomROG and arav-rog (Windows' focus-stealing protection switched off; something installed on long-lived Adom boxes does this) and 200000, the Windows default, on the fresh winvm. It matters, but it is not the fix: Windows lifts the lock once the user has been idle longer than the timeout, and someone watching a video produces no input. winvm grabbed 16 times with the lock on.
Options for a PREVENTIVE guard
WS_EX_NOACTIVATEon bridge-owned KiCad windows while a verb is in flight, cleared the moment the verb ends or the user clicks the window. Most direct. John banned it on 0.9.181 ("NEVER set WS_EX_NOACTIVATE. It blocks the user's own click") because the old hold lasted seconds after the verb. Needs John to lift the ban for the in-flight window only.- Hold the user's window on top for the length of a verb (
HWND_TOPMOSTwithout activating, removed at verb end, ledger so a crash cannot leave it stuck). KiCad may still take keyboard focus for a few milliseconds but is never drawn over the user's window. Touches a window that is not ours. - A thread-scoped
WH_CBThook inside the KiCad processes the bridge spawned, refusingHCBT_ACTIVATE. Exact, but it isSetWindowsHookExplus a DLL loaded into KiCad, and the 0.9.184 rule is "no SetWindowsHookEx, ever". - A separate desktop for bridge-owned KiCad. Nothing can ever reach the user's screen, but KiCad's OpenGL canvases are unlikely to render there, and "show it to me" would need a relaunch.
Owner's recommendation: 1, scoped to the verb in flight, with the click rule clearing it at once, and 2 as the fallback if John keeps the ban.
Acceptance
A full verb battery on a box where someone is watching a fullscreen video: zero steal events in the focus log, and the video is never interrupted.