app
Fusion - the Fusion 360 Bridge
Public Made by Adomby adom
Drive Autodesk Fusion 360 from the cloud via Adom Bridge: component libraries, IPC package generation, board layout, exports (STEP/Gerbers/BOM/CPL), fast APS cloud search, and parametric modeling.
← Commit history
server.py+32−7@@ -3750,12 +3750,24 @@ def _find_update_offer(hwnd=None) -> dict: hw = hwnd or _fusion_window_hwnd() if not hw: return {"offered": False}- for label in _UPDATE_BUTTONS:- r = _unwrap(_ad_call("desktop_find_control", {"hwnd": int(hw), "name": label}, timeout=25))- best = r.get("best") or {}- if best.get("name") and best.get("invokable"):- return {"offered": True, "button": best.get("name"), "hwnd": hw,- "detail": "Fusion is offering an update ('%s' is on screen)" % best.get("name")}+ # Scan the main window AND Fusion's owned popups - the update nag lives in the+ # "View Job Status" panel, which is a CHILD window and is only in the UIA tree while it+ # is open. Checking both is why this runs on a schedule rather than once.+ candidates = [int(hw)]+ try:+ for w in (family_windows(int(hw)) or []):+ h2 = w.get("hwnd") if isinstance(w, dict) else w+ if h2 and int(h2) != int(hw):+ candidates.append(int(h2))+ except Exception:+ pass+ for h in candidates:+ for label in _UPDATE_BUTTONS:+ r = _unwrap(_ad_call("desktop_find_control", {"hwnd": h, "name": label}, timeout=20))+ best = r.get("best") or {}+ if best.get("name") and best.get("invokable"):+ return {"offered": True, "button": best.get("name"), "hwnd": h,+ "detail": "Fusion is offering an update ('%s' is on screen)" % best.get("name")} return {"offered": False, "hwnd": hw} except Exception: return {"offered": False}@@ -3935,7 +3947,8 @@ def _fusion_window_hwnd(): # or too old). Never touches a window the user opened. _signin_windows = [] # [{sessionId, profile, kind, openedAt}] _signin_windows_lock = threading.Lock()-_JANITOR_MAX_AGE = 900 # 15 min: an OAuth window older than this is dead weight either way+_JANITOR_MAX_AGE = 900+_last_update_sweep = 0.0 # 15 min: an OAuth window older than this is dead weight either way def _track_signin_window(session_id, profile, kind="fusion"):@@ -3968,6 +3981,18 @@ def _signin_janitor_loop(): while True: try: _t2.sleep(20)+ # Periodic AUTO-UPDATE sweep. Fusion's update nag only enters the UIA tree while its+ # Job Status panel is open, so a single check at readiness time misses most of them.+ # Sweeping on a schedule catches the nag whenever Fusion actually shows it, and the+ # click is background so the user never sees any of it.+ global _last_update_sweep+ if _auto_update_enabled() and (_t2.time() - _last_update_sweep) > 300:+ _last_update_sweep = _t2.time()+ try:+ if _unwrap(_handle_fusion_readiness({}, {})).get("running"):+ _apply_fusion_update_silently()+ except Exception:+ pass with _signin_windows_lock: pending = list(_signin_windows) if not pending: