← 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

John Lauer ·1a82b6f75c ·1mo ago ·parent 5115713
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)