← Commit history

Upload 1 file(s)

John Lauer ·d19ec10b3d ·2mo ago ·parent f67084a
1 file changed +32−7
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: