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.143: SetWindowPlacement-based parking - SetWindowPos cannot move a MAXIMIZED window (the silent no-op); park demotes to normal off-screen, unpark restores true coords bottom-z, ex-maximized windows go to the taskbar minimized with restore-to-maximized
5 files changed
+63−19
BRIDGE_VERSION+1−1@@ -1 +1 @@-0.9.142+0.9.143
adom-bridge-kicad-manifest.json+5−5@@ -1,15 +1,15 @@ { "manifest_version": 1, "name": "kicad",- "version": "0.9.142",- "url": "https://wiki.adom.inc/download/adom/kicad-bridge/0.9.142/adom-bridge-kicad-v0.9.142.zip",- "sha256": "eace7f86a7bce47c92bdf7d1eab73e80222ce7b847048f07ef1a2226bc3f815a",- "size": 417950,+ "version": "0.9.143",+ "url": "https://wiki.adom.inc/download/adom/kicad-bridge/0.9.143/adom-bridge-kicad-v0.9.143.zip",+ "sha256": "18bd5164feeead23309821859a354235b9e4e231d16d6720392e182ab675a775",+ "size": 418363, "verbPrefixes": [ "kicad_" ], "healthEndpoint": "/status",- "released_at": "2026-08-17T14:25:17Z",+ "released_at": "2026-08-17T14:27:48Z", "hero": "https://wiki.adom.inc/blob/app/kicad-bridge/kicad-hero.png", "languages": [ "Python",
adom-bridge-kicad-v0.9.143.zipadded⋯ 1 unchanged line ⋯
bridge.json+1−1@@ -2,7 +2,7 @@ "manifest_version": 1, "name": "kicad", "displayName": "KiCad EDA",- "version": "0.9.142",+ "version": "0.9.143", "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+56−12@@ -420,7 +420,22 @@ def end_gui_verb() -> None: _verb_inflight = max(0, _verb_inflight - 1) +class _WINDOWPLACEMENT(ctypes.Structure if IS_WINDOWS else object):+ if IS_WINDOWS:+ _fields_ = [("length", ctypes.wintypes.UINT),+ ("flags", ctypes.wintypes.UINT),+ ("showCmd", ctypes.wintypes.UINT),+ ("ptMinPosition", ctypes.wintypes.POINT),+ ("ptMaxPosition", ctypes.wintypes.POINT),+ ("rcNormalPosition", ctypes.wintypes.RECT)]++ def _park_offscreen(hwnd) -> None:+ """Move a window fully off the visible desktop WITHOUT activation.+ SetWindowPos silently cannot move a MAXIMIZED window (the -13,-13 no-op,+ 2026-08-17), so parking goes through SetWindowPlacement: demote to+ normal-size at -32000 with SW_SHOWNOACTIVATE, remembering whether it was+ maximized so unpark can honor it.""" try: if not _user32.IsWindow(hwnd): return@@ -428,14 +443,22 @@ def _park_offscreen(hwnd) -> None: _user32.GetWindowRect(hwnd, ctypes.byref(r)) if r.left <= -20000: return # already off-screen- # KiCad applies its SAVED geometry late in init, moving itself back- # on-screen AFTER an early park — so RE-park every time we see it- # visible, but only record the true coordinates once (the first- # sighting; later sightings are just KiCad fighting the park).+ wp = _WINDOWPLACEMENT()+ wp.length = ctypes.sizeof(_WINDOWPLACEMENT)+ _user32.GetWindowPlacement(hwnd, ctypes.byref(wp))+ SW_SHOWMAXIMIZED = 3+ was_max = wp.showCmd == SW_SHOWMAXIMIZED if hwnd not in _parked:- _parked[hwnd] = (r.left, r.top)- SWP = 0x0010 | 0x0001 | 0x0004 # NOACTIVATE|NOSIZE|NOZORDER- _user32.SetWindowPos(hwnd, 0, -32000, -32000, 0, 0, SWP)+ _parked[hwnd] = (r.left, r.top, was_max)+ wp.showCmd = SW_SHOWNOACTIVATE # 4+ w = max(200, wp.rcNormalPosition.right - wp.rcNormalPosition.left)+ h = max(150, wp.rcNormalPosition.bottom - wp.rcNormalPosition.top)+ wp.rcNormalPosition.left = -32000+ wp.rcNormalPosition.top = -32000+ wp.rcNormalPosition.right = -32000 + w+ wp.rcNormalPosition.bottom = -32000 + h+ wp.flags = 0+ _user32.SetWindowPlacement(hwnd, ctypes.byref(wp)) except Exception: pass @@ -445,11 +468,32 @@ def _unpark(hwnd, to_bottom: bool = True) -> None: 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))+ x, y, was_max = (pos if len(pos) == 3 else (pos[0], pos[1], False))+ wp = _WINDOWPLACEMENT()+ wp.length = ctypes.sizeof(_WINDOWPLACEMENT)+ _user32.GetWindowPlacement(hwnd, ctypes.byref(wp))+ w = max(200, wp.rcNormalPosition.right - wp.rcNormalPosition.left)+ h = max(150, wp.rcNormalPosition.bottom - wp.rcNormalPosition.top)+ wp.rcNormalPosition.left = x+ wp.rcNormalPosition.top = y+ wp.rcNormalPosition.right = x + w+ wp.rcNormalPosition.bottom = y + h+ if was_max and to_bottom:+ # can't re-maximize without activation: hand it to the taskbar,+ # minimized with restore-to-maximized — the user's click brings it+ # back exactly like a normal maximized window (John's contract).+ WPF_RESTORETOMAXIMIZED = 2+ wp.flags = WPF_RESTORETOMAXIMIZED+ wp.showCmd = 7 # SW_SHOWMINNOACTIVE+ _user32.SetWindowPlacement(hwnd, ctypes.byref(wp))+ else:+ wp.flags = 0+ wp.showCmd = SW_SHOWNOACTIVATE+ _user32.SetWindowPlacement(hwnd, ctypes.byref(wp))+ if to_bottom:+ HWND_BOTTOM = 1+ _user32.SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0,+ 0x0010 | 0x0001 | 0x0002) # NOACTIVATE|NOSIZE|NOMOVE except Exception: pass