app
KiCad - the KiCad Bridge
Public Made by Adomby adom
Reference implementation of the KiCad bridge: multi-instance Python server, forward path via kicad-cli, reverse path via in-process plugin. Most complex of the three bundled bridges.
← Commit history
v0.9.141: 50ms parking sweep (deterministic) - baselines existing windows at verb start, parks anything newer off-screen while verbs/guards are live; complements the SHOW hook which arms but gets no events on some sessions
5 files changed
+71−9
BRIDGE_VERSION+1−1@@ -1 +1 @@-0.9.140+0.9.141
adom-bridge-kicad-manifest.json+5−5@@ -1,15 +1,15 @@ { "manifest_version": 1, "name": "kicad",- "version": "0.9.140",- "url": "https://wiki.adom.inc/download/adom/kicad-bridge/0.9.140/adom-bridge-kicad-v0.9.140.zip",- "sha256": "ededb375e362caeef7b4db7baad7ad3f3622ecc1f60bd7d4225556d6e6977e66",- "size": 417463,+ "version": "0.9.141",+ "url": "https://wiki.adom.inc/download/adom/kicad-bridge/0.9.141/adom-bridge-kicad-v0.9.141.zip",+ "sha256": "4c30eb514b5cb3df2890750a99bd62c702f932f2071decdd4309617483c58b2b",+ "size": 417817, "verbPrefixes": [ "kicad_" ], "healthEndpoint": "/status",- "released_at": "2026-08-17T14:22:15Z",+ "released_at": "2026-08-17T14:23:57Z", "hero": "https://wiki.adom.inc/blob/app/kicad-bridge/kicad-hero.png", "languages": [ "Python",
adom-bridge-kicad-v0.9.141.zipadded⋯ 1 unchanged line ⋯
bridge.json+1−1@@ -2,7 +2,7 @@ "manifest_version": 1, "name": "kicad", "displayName": "KiCad EDA",- "version": "0.9.140",+ "version": "0.9.141", "description": "Reverse bridge for KiCad \u2014 board/schematic introspection, lint via kicad-cli, plugin install, multi-instance probe, in-process DRC.", "homepage": "https://wiki.adom.inc/adom/adom-bridge", "author": "Adom Inc.",
handlers/win_focus.py+64−2@@ -346,11 +346,73 @@ _parked: dict = {} # hwnd -> (x, y) _verb_inflight = 0 +_park_baseline: set = set()+_park_sweep_started = False+++def _enum_kicad_hwnds() -> set:+ out = set()+ try:+ WNDENUMPROC = ctypes.WINFUNCTYPE(ctypes.c_bool, ctypes.wintypes.HWND,+ ctypes.wintypes.LPARAM)+ def cb(h, _l):+ try:+ if _user32.IsWindowVisible(h) and is_kicad_window(h):+ out.add(h)+ except Exception:+ pass+ return True+ cbp = WNDENUMPROC(cb)+ _user32.EnumWindows(cbp, 0)+ except Exception:+ pass+ return out+++def _start_park_sweep() -> None:+ """50ms parking sweep, active only while a GUI verb is in flight or a guard+ is armed: any KiCad window NOT in the verb-start baseline is suppressed and+ parked off-screen the moment it enumerates. Deterministic complement to the+ SHOW hook (which arms but receives no events on some sessions)."""+ global _park_sweep_started+ if _park_sweep_started or not IS_WINDOWS:+ return+ _park_sweep_started = True+ import threading+ import time as _t++ def _loop():+ while True:+ try:+ if _verb_inflight > 0 or _guard_count > 0:+ if _t.monotonic() >= _expected_fg_until:+ for h in _enum_kicad_hwnds() - _park_baseline:+ suppress_activation(h)+ _park_offscreen(h)+ _t.sleep(0.05)+ else:+ _t.sleep(0.25)+ except Exception:+ try:+ _t.sleep(0.5)+ except Exception:+ pass++ try:+ threading.Thread(target=_loop, daemon=True, name="kicad-park-sweep").start()+ except Exception:+ pass++ def begin_gui_verb() -> None:- """Dispatcher marks a GUI verb in flight so the SHOW hook parks windows- created DURING the handler (guards only arm after it returns)."""+ """Dispatcher marks a GUI verb in flight; windows existing NOW are the+ user's (baseline) — anything newer gets parked by the 50ms sweep.""" global _verb_inflight+ if _verb_inflight == 0 and _guard_count == 0:+ _park_baseline.clear()+ _park_baseline.update(_enum_kicad_hwnds() - set(_parked.keys())) _verb_inflight += 1+ _start_park_sweep() def end_gui_verb() -> None: