← Commit history

Update 4 file(s)

John Lauer ·c3c9b54c22 ·1mo ago ·parent df03435
4 files changed +63−14
BRIDGE_VERSION+1−1
@@ -1 +1 @@-0.9.200\ No newline at end of file+0.9.201\ No newline at end of file
adom-bridge-kicad-manifest.json+5−5
@@ -1,15 +1,15 @@ {   "manifest_version": 1,   "name": "kicad",-  "version": "0.9.200",-  "url": "https://wiki.adom.inc/download/adom/kicad-bridge/0.9.200/adom-bridge-kicad-v0.9.200.zip",-  "sha256": "799b09738cff9de8bdb1112cfe80267052403cdeaa12e7874e4e4c875cd27674",-  "size": 470688,+  "version": "0.9.201",+  "url": "https://wiki.adom.inc/download/adom/kicad-bridge/0.9.201/adom-bridge-kicad-v0.9.201.zip",+  "sha256": "ccd4b1259f274c7c23d843d3477f905317a264ee90173cf6c692a64cefd3873f",+  "size": 471341,   "verbPrefixes": [     "kicad_"   ],   "healthEndpoint": "/status",-  "released_at": "2026-08-20T09:35:00Z",+  "released_at": "2026-08-20T09:55:00Z",   "hero": "https://wiki.adom.inc/blob/app/kicad-bridge/kicad-hero.png",   "languages": [     "Python",
bridge.json+1−1
@@ -2,7 +2,7 @@   "manifest_version": 1,   "name": "kicad",   "displayName": "KiCad EDA",-  "version": "0.9.200",+  "version": "0.9.201",   "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/kicad_ui.py+56−7
@@ -266,7 +266,44 @@ def _write_bmp(path: str, width: int, height: int, pixel_data: bytes):   -def _canvas_uniformity(pixels: bytes, width: int, height: int) -> dict:++def _gl_canvas_rect(hwnd: int):+    """The drawing canvas's rect, in coordinates relative to `hwnd`'s window box.++    KiCad's canvas is a `wxGLCanvas` child (confirmed live: 890x572 inside a+    Symbol Editor). Finding it beats guessing by percentage - 0.9.200 sampled a+    fixed fraction of the window and landed on the Footprint Editor's toolbar+    and Appearance panel, whose colour swatches read as "drawn" no matter what+    the canvas was doing. Returns None when no GL canvas exists."""+    try:+        found = []+        WNDENUMPROC = ctypes.WINFUNCTYPE(ctypes.c_bool, ctypes.wintypes.HWND,+                                         ctypes.wintypes.LPARAM)++        def cb(child, _l):+            buf = ctypes.create_unicode_buffer(256)+            user32.GetClassNameW(child, buf, 256)+            if buf.value == "wxGLCanvas":+                r = ctypes.wintypes.RECT()+                user32.GetWindowRect(child, ctypes.byref(r))+                found.append((r.left, r.top, r.right, r.bottom))+                return False+            return True++        c = WNDENUMPROC(cb)+        _callbacks.append(c)+        user32.EnumChildWindows(hwnd, c, 0)+        _callbacks.remove(c)+        if not found:+            return None+        pr = ctypes.wintypes.RECT()+        user32.GetWindowRect(hwnd, ctypes.byref(pr))+        l, t, rr, b = found[0]+        return (l - pr.left, t - pr.top, rr - pr.left, b - pr.top)+    except Exception:+        return None++def _canvas_uniformity(pixels: bytes, width: int, height: int, rect=None) -> dict:     """Is the editor's drawing CANVAS actually rendered, or an empty rectangle?      0.9.200. A capture can show the right title, the right tree row and the right@@ -280,9 +317,19 @@ def _canvas_uniformity(pixels: bytes, width: int, height: int) -> dict:     BGRA buffer and count distinct colours. A drawn canvas carries grid dots,     axes and the part itself; an unrendered one is one flat colour."""     try:-        # The canvas is the large area right of the library/properties panels.-        x0, x1 = int(width * 0.35), int(width * 0.95)-        y0, y1 = int(height * 0.15), int(height * 0.85)+        if rect:+            # Inset a few percent so window/canvas border pixels never count as+            # "content" on an otherwise empty canvas.+            l, t, r, b = rect+            dx, dy = int((r - l) * 0.04), int((b - t) * 0.04)+            x0, x1, y0, y1 = l + dx, r - dx, t + dy, b - dy+        else:+            # No GL canvas found: fall back to a coarse guess, and say so, rather+            # than reporting a confident verdict about a region we did not locate.+            x0, x1 = int(width * 0.35), int(width * 0.95)+            y0, y1 = int(height * 0.15), int(height * 0.85)+        x0, y0 = max(0, x0), max(0, y0)+        x1, y1 = min(width, x1), min(height, y1)         if x1 <= x0 or y1 <= y0:             return {"checked": False}         step_x = max(1, (x1 - x0) // 60)@@ -297,9 +344,11 @@ def _canvas_uniformity(pixels: bytes, width: int, height: int) -> dict:                 samples += 1                 if len(colors) > 12:               # clearly drawn; stop early                     return {"checked": True, "distinctColors": len(colors),-                            "rendered": True, "samples": samples}+                            "rendered": True, "samples": samples,+                            "region": "glCanvas" if rect else "approx"}         return {"checked": True, "distinctColors": len(colors),-                "rendered": len(colors) > 3, "samples": samples}+                "rendered": len(colors) > 3, "samples": samples,+                "region": "glCanvas" if rect else "approx"}     except Exception:         return {"checked": False} @@ -366,7 +415,7 @@ def _screenshot_hwnd(hwnd: int, label: str = "", max_dim: int = 1568) -> dict:     pixel_buf = ctypes.create_string_buffer(buf_size)     gdi32.GetDIBits(hdc_mem, hbmp, 0, height, pixel_buf, ctypes.byref(bmi), DIB_RGB_COLORS) -    _canvas = _canvas_uniformity(pixel_buf.raw, width, height)+    _canvas = _canvas_uniformity(pixel_buf.raw, width, height, _gl_canvas_rect(hwnd))      gdi32.SelectObject(hdc_mem, old_bmp)     gdi32.DeleteObject(hbmp)