← Commit history

v0.9.95 (#26): FP path gets plugin-free UIA 3D-viewer tier; 3D window poll 3s->9s for slow renders

John Lauer ·82bc1e9009 ·2mo ago ·parent 136a4be
5 files changed +41−9
BRIDGE_VERSION+1−1
@@ -1 +1 @@-0.9.94+0.9.95
adom-bridge-kicad-manifest.json+5−5
@@ -1,15 +1,15 @@ {   "manifest_version": 1,   "name": "kicad",-  "version": "0.9.94",-  "url": "https://wiki.adom.inc/download/adom/kicad-bridge/0.9.94/adom-bridge-kicad-v0.9.94.zip",-  "sha256": "297d99612fab0cdfac9f2fdd1b645fa4b4a2ac77844ce1671667526b2606cbd9",-  "size": 387818,+  "version": "0.9.95",+  "url": "https://wiki.adom.inc/download/adom/kicad-bridge/0.9.95/adom-bridge-kicad-v0.9.95.zip",+  "sha256": "526b6024d87c7748d12bc67ecae5d3f740dd45a5b47890dfdfdc803a706bdbc2",+  "size": 388116,   "verbPrefixes": [     "kicad_"   ],   "healthEndpoint": "/status",-  "released_at": "2026-08-14T18:56:33Z",+  "released_at": "2026-08-14T19:19:18Z",   "hero": "https://wiki.adom.inc/blob/app/kicad-bridge/kicad-hero.png",   "languages": [     "Python",
adom-bridge-kicad-v0.9.95.zipadded
⋯ 1 unchanged line ⋯
bridge.json+1−1
@@ -2,7 +2,7 @@   "manifest_version": 1,   "name": "kicad",   "displayName": "KiCad EDA",-  "version": "0.9.94",+  "version": "0.9.95",   "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/open_footprint_editor.py+34−2
@@ -776,6 +776,17 @@ def _find_pcb_editor() -> int | None:     return None  +def _poll_3d_window(rounds: int = 12):+    """Wait for a real 3D Viewer WINDOW to appear (render can lag the invoke,+    esp. on software-OpenGL). Process-verified via _find_windows_by_title."""+    for _ in range(max(1, rounds)):+        time.sleep(0.75)+        w = _find_windows_by_title("3D Viewer")+        if w:+            return w+    return []++ def handle_open_3d_viewer(kicad_info: dict, args: dict) -> dict:     """Open the 3D Viewer from the Footprint Editor or the PCB Editor. @@ -873,6 +884,28 @@ def handle_open_3d_viewer(kicad_info: dict, args: dict) -> dict:         except Exception as e:  # pylint: disable=broad-except             fp_pathways.append(f"plugin-error:{type(e).__name__}") +        # Tier 1.5 (v0.9.95, #26): UIA background Invoke of the "3D Viewer" control on+        # the Footprint Editor — programmatic, no foreground/cursor, and crucially+        # PLUGIN-FREE (the FP path previously dead-ended when pcbnew's plugin hadn't+        # bound, the #21/#26 late-bind). Same primitive the open_footprint tier uses.+        try:+            from handlers import uia+            r = uia.uia_invoke(fp_hwnd, contains="3D Viewer")+            if r.get("ok"):+                fp_pathways.append("uia")+                windows = _poll_3d_window(12)+                if windows:+                    return {+                        "success": True,+                        "output": f"3D Viewer opened from Footprint Editor via UIA: {windows[0][1]}",+                        "pathway": "uia",+                        "pathwaysTried": fp_pathways,+                    }+            else:+                fp_pathways.append(f"uia-{r.get('reason','miss')}")+        except Exception as e:  # pylint: disable=broad-except+            fp_pathways.append(f"uia-error:{type(e).__name__}")+         # Opt-in disruptive fallback: Alt+3 keystroke (needs the FP window foregrounded,         # so it steals focus) — only when the caller explicitly allows it.         if args.get("allowFocusSteal"):@@ -955,8 +988,7 @@ def handle_open_3d_viewer(kicad_info: dict, args: dict) -> dict:             r = uia.uia_invoke(pcb_hwnd, contains="3D Viewer")             if r.get("ok"):                 pathways_tried.append("uia")-                time.sleep(3.0)-                windows = _find_windows_by_title("3D Viewer")+                windows = _poll_3d_window(12)                 if windows:                     return {                         "success": True,