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.145: bridge-created windows stay bridge-created across verbs (rebaselining adopted the previous verb's window as the user's); parked windows are defended between verbs and unparked to true coords bottom-z after 2s of quiet
5 files changed
+37−11
BRIDGE_VERSION+1−1@@ -1 +1 @@-0.9.144+0.9.145
adom-bridge-kicad-manifest.json+5−5@@ -1,15 +1,15 @@ { "manifest_version": 1, "name": "kicad",- "version": "0.9.144",- "url": "https://wiki.adom.inc/download/adom/kicad-bridge/0.9.144/adom-bridge-kicad-v0.9.144.zip",- "sha256": "7e580af00830888e3bcbfff3f8c33e4bced35b41067fb639aeb9cfccdce2a9b5",- "size": 418539,+ "version": "0.9.145",+ "url": "https://wiki.adom.inc/download/adom/kicad-bridge/0.9.145/adom-bridge-kicad-v0.9.145.zip",+ "sha256": "ff0fba27d4a49fa94022e1e633a9dd678488c306e73b058f06c34e86e042a91b",+ "size": 418858, "verbPrefixes": [ "kicad_" ], "healthEndpoint": "/status",- "released_at": "2026-08-17T14:29:00Z",+ "released_at": "2026-08-17T14:31:45Z", "hero": "https://wiki.adom.inc/blob/app/kicad-bridge/kicad-hero.png", "languages": [ "Python",
adom-bridge-kicad-v0.9.145.zipadded⋯ 1 unchanged line ⋯
bridge.json+1−1@@ -2,7 +2,7 @@ "manifest_version": 1, "name": "kicad", "displayName": "KiCad EDA",- "version": "0.9.144",+ "version": "0.9.145", "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+30−4@@ -360,6 +360,7 @@ _verb_inflight = 0 _park_baseline: set = set()+_bridge_windows: set = set() # windows the BRIDGE created (persists across verbs) _park_sweep_started = False @@ -395,14 +396,33 @@ def _start_park_sweep() -> None: import time as _t def _loop():+ quiet_since = None while True: try:- if _verb_inflight > 0 or _guard_count > 0:+ active = _verb_inflight > 0 or _guard_count > 0+ if active:+ quiet_since = None if _t.monotonic() >= _expected_fg_until: for h in _enum_kicad_hwnds() - _park_baseline:+ _bridge_windows.add(h) suppress_activation(h) _park_offscreen(h) _t.sleep(0.05)+ elif _parked:+ # bridge quiet but windows still parked: keep re-parking+ # fighters briefly, then place everything at its true+ # position (bottom-z) once things have settled for 2s.+ if quiet_since is None:+ quiet_since = _t.monotonic()+ if _t.monotonic() - quiet_since >= 2.0:+ unpark_all()+ quiet_since = None+ else:+ for h in list(_parked.keys()):+ _park_offscreen(h)+ _t.sleep(0.05)+ continue+ _t.sleep(0.1) else: _t.sleep(0.25) except Exception:@@ -418,12 +438,18 @@ def _start_park_sweep() -> None: def begin_gui_verb() -> None:- """Dispatcher marks a GUI verb in flight; windows existing NOW are the- user's (baseline) — anything newer gets parked by the 50ms sweep."""+ """Dispatcher marks a GUI verb in flight; windows existing NOW that the+ bridge did NOT create are the user's (baseline) — anything newer gets+ parked by the 50ms sweep. Bridge-created windows stay bridge-created+ across verbs (rebaselining used to adopt the previous verb's window as+ the user's — the parking no-op of 2026-08-17).""" global _verb_inflight if _verb_inflight == 0 and _guard_count == 0:+ for h in list(_bridge_windows):+ if not _user32.IsWindow(h):+ _bridge_windows.discard(h) _park_baseline.clear()- _park_baseline.update(_enum_kicad_hwnds() - set(_parked.keys()))+ _park_baseline.update(_enum_kicad_hwnds() - set(_parked.keys()) - _bridge_windows) _verb_inflight += 1 _start_park_sweep()