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.138: off-screen parking (John's design) - the SHOW hook teleports new KiCad windows to -32000,-32000 before first visible paint, unparks to true coords at bottom-z when bridge work ends; taskbar + PrintWindow unaffected
5 files changed
+65−7
BRIDGE_VERSION+1−1@@ -1 +1 @@-0.9.137+0.9.138
adom-bridge-kicad-manifest.json+5−5@@ -1,15 +1,15 @@ { "manifest_version": 1, "name": "kicad",- "version": "0.9.137",- "url": "https://wiki.adom.inc/download/adom/kicad-bridge/0.9.137/adom-bridge-kicad-v0.9.137.zip",- "sha256": "47efeabe8f26f2e15720a68c9b3eac912e6dc160347bf06676ad89b373d8891e",- "size": 416523,+ "version": "0.9.138",+ "url": "https://wiki.adom.inc/download/adom/kicad-bridge/0.9.138/adom-bridge-kicad-v0.9.138.zip",+ "sha256": "7fc82b50e324030b7f99e2026a24b83fee155cfd8ccdde804e8bb5d87f82fe36",+ "size": 417196, "verbPrefixes": [ "kicad_" ], "healthEndpoint": "/status",- "released_at": "2026-08-17T14:11:48Z",+ "released_at": "2026-08-17T14:19:28Z", "hero": "https://wiki.adom.inc/blob/app/kicad-bridge/kicad-hero.png", "languages": [ "Python",
adom-bridge-kicad-v0.9.138.zipadded⋯ 1 unchanged line ⋯
bridge.json+1−1@@ -2,7 +2,7 @@ "manifest_version": 1, "name": "kicad", "displayName": "KiCad EDA",- "version": "0.9.137",+ "version": "0.9.138", "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+58@@ -329,6 +329,61 @@ def get_focus_events() -> list: # an expect_foreground() window — outside bridge work the click-aware polling # sentinel owns classification, so user clicks into KiCad always work. # ---------------------------------------------------------------------------+# ---------------------------------------------------------------------------+# OFF-SCREEN PARKING (0.9.138, John's design, 2026-08-17 verbatim: "open them+# at xy screen coordinates that are way off in a non-visible part of the xy+# layout of the screen, then background those windows, then place them into+# the correct xy position of my screen in the background"). NOACTIVATE stops+# focus theft, but a freshly CREATED window still PAINTS near the top of the+# z-order — visible over the user's work even unfocused. Parking closes that:+# the SHOW hook teleports a new KiCad window to (-32000,-32000) before its+# first paint lands on the visible desktop; when bridge work ends (or the+# window must be shown deliberately) it is placed back at its real coordinates+# AT THE BOTTOM of the z-order. Taskbar buttons keep working; PrintWindow+# capture works off-screen; the user sees nothing appear.+# ---------------------------------------------------------------------------+_parked: dict = {} # hwnd -> (x, y)+++def _park_offscreen(hwnd) -> None:+ try:+ if hwnd in _parked or not _user32.IsWindow(hwnd):+ return+ r = ctypes.wintypes.RECT()+ _user32.GetWindowRect(hwnd, ctypes.byref(r))+ if r.left <= -20000:+ return # already off-screen+ _parked[hwnd] = (r.left, r.top)+ SWP = 0x0010 | 0x0001 | 0x0004 # NOACTIVATE|NOSIZE|NOZORDER+ _user32.SetWindowPos(hwnd, 0, -32000, -32000, 0, 0, SWP)+ except Exception:+ pass+++def _unpark(hwnd, to_bottom: bool = True) -> None:+ try:+ pos = _parked.pop(hwnd, None)+ if pos is None or not _user32.IsWindow(hwnd):+ return+ HWND_BOTTOM = 1+ SWP = 0x0010 | 0x0001 # NOACTIVATE|NOSIZE+ _user32.SetWindowPos(hwnd, HWND_BOTTOM if to_bottom else 0,+ pos[0], pos[1], 0, 0,+ SWP | (0 if to_bottom else 0x0004))+ except Exception:+ pass+++def unpark_all() -> int:+ """Place every parked window back at its true coordinates, bottom-z,+ no activation. Called when the last guard exits."""+ n = 0+ for h in list(_parked.keys()):+ _unpark(h, to_bottom=True)+ n += 1+ return n++ _hook_started = False @@ -363,6 +418,7 @@ def start_focus_event_hook() -> None: return if event == EVENT_OBJECT_SHOW: suppress_activation(hwnd)+ _park_offscreen(hwnd) elif event == EVENT_SYSTEM_FOREGROUND: _push_kicad_to_background(hwnd) try:@@ -556,6 +612,7 @@ def restore_foreground_persistent(hwnd, seconds: float = 6.0, interval: float = else: last = True if last:+ unpark_all() allow_activation_all() try:@@ -592,6 +649,7 @@ def bring_to_user(hwnd, reason: str = "") -> bool: import time as _t _t.sleep(1.2) # let the caption render BEFORE the window moves expect_foreground(20.0) # tell the sentinel this foreground is sanctioned+ _unpark(hwnd, to_bottom=False) # if parked off-screen, put it back first allow_activation(hwnd) # a suppressed window can't be activated _user32.ShowWindow(hwnd, 9) # SW_RESTORE (in case minimized) return _set_foreground_robust(hwnd)