← Commit history

v0.9.164: heal window usability by INSPECTION - a window suppressed by an earlier bridge process was unknown to the new one, so a stale WS_EX_NOACTIVATE (unclickable, no taskbar button) could survive every later fix. Now read off every KiCad window at boot and every 20s idle

John Lauer ·cdd33c45a5 ·1mo ago ·parent 53eeaff
6 files changed +63−7
BRIDGE_VERSION+1−1
@@ -1 +1 @@-0.9.163+0.9.164
adom-bridge-kicad-manifest.json+5−5
@@ -1,15 +1,15 @@ {   "manifest_version": 1,   "name": "kicad",-  "version": "0.9.163",-  "url": "https://wiki.adom.inc/download/adom/kicad-bridge/0.9.163/adom-bridge-kicad-v0.9.163.zip",-  "sha256": "40e6868e0f9f247c4006bcd72ce7d519a22d7005e7660c000addb2340ecc7c7c",-  "size": 443052,+  "version": "0.9.164",+  "url": "https://wiki.adom.inc/download/adom/kicad-bridge/0.9.164/adom-bridge-kicad-v0.9.164.zip",+  "sha256": "74b29b5d9c35f5095634890c710a6ca2b476ad64292d2513b21bd1488ba1b236",+  "size": 443664,   "verbPrefixes": [     "kicad_"   ],   "healthEndpoint": "/status",-  "released_at": "2026-08-18T11:17:43Z",+  "released_at": "2026-08-18T11:21:42Z",   "hero": "https://wiki.adom.inc/blob/app/kicad-bridge/kicad-hero.png",   "languages": [     "Python",
adom-bridge-kicad-v0.9.164.zipadded
⋯ 1 unchanged line ⋯
bridge.json+1−1
@@ -2,7 +2,7 @@   "manifest_version": 1,   "name": "kicad",   "displayName": "KiCad EDA",-  "version": "0.9.163",+  "version": "0.9.164",   "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+50
@@ -647,6 +647,51 @@ def sanitize_kicad_session() -> int:     return removed  +_last_usability_heal = 0.0+++def heal_window_usability() -> int:+    """Make every KiCad window the bridge is NOT actively working with fully+    usable again: clickable (no stale WS_EX_NOACTIVATE), present in the taskbar+    (WS_EX_APPWINDOW), iconed, and on-screen.++    0.9.164 - John: "why is it that when i try to click to see one of your kicad+    windows it doesn't work?" Exactly right, and the gap is subtler than the+    0.9.160 fix: suppression is cleared through _noactivated, which lives in the+    bridge PROCESS. Any window suppressed by an earlier bridge (or one that died+    mid-verb) is unknown to the new process, so nothing ever clears it - the+    window stays permanently un-clickable and taskbar-less no matter how many+    fixes ship afterwards. So we heal by INSPECTION, not by memory: read the+    style off every KiCad window and clear what should not be there."""+    global _last_usability_heal+    import time as _t+    _last_usability_heal = _t.monotonic()+    healed = 0+    if not IS_WINDOWS:+        return healed+    try:+        busy = _verb_inflight > 0 or _guard_count > 0+        for h in _enum_kicad_hwnds():+            if busy and h in _parked:+                continue  # mid-verb: this window is legitimately suppressed+            try:+                cur = _get_exstyle(h)+                want = (cur & ~WS_EX_NOACTIVATE) | WS_EX_APPWINDOW+                if want != cur:+                    _set_exstyle(h, want)+                    _noactivated.discard(h)+                    _ensure_window_icon(h)+                    healed += 1+                    print(f"[focus] usability heal: cleared stale suppression on {h}",+                          file=sys.stderr)+                _sane_position(h)+            except Exception:+                pass+    except Exception:+        pass+    return healed++ def heal_offscreen_windows() -> int:     """Boot repair (John, 2026-08-17: "when the user goes to open kicad normally     ... it starts way offscreen and kicad doesn't fix itself"): if a parked@@ -781,6 +826,11 @@ def _start_park_sweep() -> None:                         continue                     _t.sleep(0.1)                 else:+                    if _t.monotonic() - _last_usability_heal > 20:+                        try:+                            heal_window_usability()+                        except Exception:+                            pass                     if _t.monotonic() - _last_sanitize > 60:                         try:                             sanitize_kicad_session()
server.py+6
@@ -1108,6 +1108,12 @@ def main():         win_focus.heal_offscreen_windows()     except Exception:         pass+    # 0.9.164: a window suppressed by an EARLIER bridge process is unknown to+    # this one, so nothing would ever clear it - heal by inspection at boot.+    try:+        win_focus.heal_window_usability()+    except Exception:+        pass     # Bridge shutdown must never strand parked windows either.     try:         import atexit