← Commit history

0.9.289: John, 2026-09-03: no caption on a Symbol Editor launch or rescan reopen (the 0.9.285 one was large, shown too long, and wrong on his laptop: it promised 'behind your window' while KiCad raised itself in front while loading). Launch is silent. _foreground now also reports editorInFrontAtEnd, measured from AD's z-order at return time, so a response never claims background about a window the user can see on top. Dev skill records the rule: one early look, no fighting the user for the foreground, captions only on the opt-in allowFocusSteal path and short.

John Lauer ·7c94fb4d2d ·1mo ago ·parent 0286cc0
4 files changed +28−23
handlers/open_symbol_editor.py+28−23
@@ -375,24 +375,31 @@ _EDITOR_OPENED_AT: dict = {}  # hwnd -> epoch seconds when this module saw it ap   def _caption_new_frame(user_top: dict | None, rescan: bool = False) -> None:-    """John's rule: when you know a window will appear, say why, on screen, first."""+    """Deliberately does nothing (John, 2026-09-03): the on-screen caption+    before an editor launch was large, ugly, shown far too long, and on his+    laptop it was WRONG (it promised "behind your window" while KiCad came up+    in front). A caption that lies is worse than none. The launch is silent;+    the response reports, measured, whether the editor ended up in front+    (editorInFrontAtEnd). Captions remain only for the opt-in allowFocusSteal+    path, and short."""+    return None+++def _editor_in_front() -> bool | None:+    """Is a Symbol Editor the top window RIGHT NOW (measured, no action)?+    John, 2026-09-03: the guard's one early look said "did not come to the+    top" while KiCad then raised itself as it finished loading, and he watched+    it come up in front. Report the end state too, so a response never says+    "background" about a window the user can see on top. None if unreadable."""     try:-        from handlers import ad_client-        what = ("re-opening KiCad's Symbol Editor so it re-indexes the library (a new symbol was installed)"-                if rescan else "opening KiCad's Symbol Editor (it indexes every symbol library on open)")-        back = " It will be placed behind your current window." if user_top and not user_top.get("isKicad") else ""-        # Name the calling thread (John, 2026-09-03: a caption on his laptop-        # could not tell him WHICH thread was about to open a window).-        try:-            import caller_identity-            who = str(caller_identity.thread_name() or "").strip()-        except Exception:  # pylint: disable=broad-except-            who = ""-        prefix = f"Adom Bridge (thread {who}): " if who and who != "unknown" else "Adom Bridge: "-        ad_client.call("desktop_caption", {"text": (prefix + what + back)[:180], "seconds": 6,-                                           "reason": f"Warn the user before a KiCad window appears on their screen (caller: {who or 'unknown'})"})+        from handlers import kicad_windows+        rows = [r for r in (kicad_windows.find(all_windows=True, fresh=True) or []) if r.get("z") is not None]+        if not rows:+            return None+        top = sorted(rows, key=lambda r: r.get("z"))[0]+        return bool(kicad_windows._is_kicad(top) and "symbol editor" in str(top.get("title", "")).lower())     except Exception:  # pylint: disable=broad-except-        pass+        return None   def _user_top_window() -> dict | None:@@ -1054,7 +1061,6 @@ def _handle_open_symbol_editor_inner(kicad_info: dict, args: dict) -> dict:     _user_top = None     if not sym_hwnd:         _user_top = _user_top_window()-        _caption_new_frame(_user_top)     _step("Symbol Editor already open" if sym_hwnd           else "opening the Symbol Editor (KiCad indexes every symbol library here)", 10) @@ -1068,7 +1074,6 @@ def _handle_open_symbol_editor_inner(kicad_info: dict, args: dict) -> dict:             rescanned = True             sym_hwnd = 0             _user_top = _user_top_window()-            _caption_new_frame(_user_top, rescan=True)             pathways_tried.append("rescan-closed-stale-editor")         else:             pathways_tried.append("rescan-close-failed")@@ -1346,7 +1351,7 @@ def _handle_open_symbol_editor_inner(kicad_info: dict, args: dict) -> dict:             "output": f"Symbol '{search_text}' loaded (background win32 path): {_get_symbol_editor_title()}",             "via": "win32-background",             "navigation": dict(_LAST_NAV_TRACE),-            "_foreground": dict(_LAST_FG_REPORT),+            "_foreground": {**_LAST_FG_REPORT, "editorInFrontAtEnd": _editor_in_front()},             "rescanned": rescanned,             "editorCloseVia": _LAST_CLOSE_HOW if rescanned else None,             **_resolved_fields(_get_symbol_editor_title(), library_name),@@ -1380,7 +1385,7 @@ def _handle_open_symbol_editor_inner(kicad_info: dict, args: dict) -> dict:             "rescanned": rescanned,             "editorCloseVia": _LAST_CLOSE_HOW if rescanned else None,             "navigation": dict(_LAST_NAV_TRACE),-            "_foreground": dict(_LAST_FG_REPORT),+            "_foreground": {**_LAST_FG_REPORT, "editorInFrontAtEnd": _editor_in_front()},             **_resolved_fields(_get_symbol_editor_title(), library_name),             "error": (f"The Symbol Editor is open and one background navigation ran, but the title did not "                       f"confirm '{search_text}' before this call's time budget ended "@@ -1398,7 +1403,7 @@ def _handle_open_symbol_editor_inner(kicad_info: dict, args: dict) -> dict:                       f"{_get_symbol_editor_title()}",             "via": "win32-background",             "navigation": dict(_LAST_NAV_TRACE),-            "_foreground": dict(_LAST_FG_REPORT),+            "_foreground": {**_LAST_FG_REPORT, "editorInFrontAtEnd": _editor_in_front()},             "attempts": 2,             **_resolved_fields(_get_symbol_editor_title(), library_name),             "rescanned": rescanned,@@ -1504,13 +1509,13 @@ def _handle_open_symbol_editor_inner(kicad_info: dict, args: dict) -> dict:                 # So report the paths, measured, and say only what they show.                 **_stale_explanation(kicad_info, search_text),                 "navigation": dict(_LAST_NAV_TRACE),-            "_foreground": dict(_LAST_FG_REPORT),+            "_foreground": {**_LAST_FG_REPORT, "editorInFrontAtEnd": _editor_in_front()},             }         return {             "success": False, "editorOpened": True, "symbolLoaded": False,             "attempts": 2,             "navigation": dict(_LAST_NAV_TRACE),-            "_foreground": dict(_LAST_FG_REPORT),+            "_foreground": {**_LAST_FG_REPORT, "editorInFrontAtEnd": _editor_in_front()},             "errorCode": "navigation_failed",             "staleVeto": _stale_veto or None,             **_resolved_fields(_get_symbol_editor_title(), library_name),
install.sh

  
start.bat

  
uninstall.sh