"""ensure_ui_ready:probe → wake → probe。""" from __future__ import annotations from typing import Optional, Union from .errors import DesktopWakeError, ERR_PROVIDER_COLD, ERR_WAKE_FAILED from .probe import probe from .profiles import load_profile from .types import EnsureResult, Profile from .wake import wake from .window import find_hwnd_for_profile, require_windows def ensure_ui_ready( profile: Union[str, Profile] = "wecom", *, hwnd: Optional[int] = None, raise_on_cold: bool = True, ) -> EnsureResult: """保证目标窗 UIA 树可用。 已暖则直接返回;否则跑唤醒策略梯再探测。 ``raise_on_cold=True``(默认)时仍冷则抛 ``DesktopWakeError``。 """ require_windows() prof = load_profile(profile) if isinstance(profile, str) else profile h = find_hwnd_for_profile(prof, hwnd=hwnd) before = probe(prof, hwnd=h) if before.warm: return EnsureResult( hwnd=h, profile_id=prof.id, warm=True, probe_before=before, probe_after=before, steps=[], wake_applied=False, ) steps = wake(prof, hwnd=h, stop_when_warm=True) after = probe(prof, hwnd=h) result = EnsureResult( hwnd=h, profile_id=prof.id, warm=after.warm, probe_before=before, probe_after=after, steps=steps, wake_applied=True, ) if after.warm or not raise_on_cold: return result code = ERR_WAKE_FAILED if steps else ERR_PROVIDER_COLD raise DesktopWakeError( code, f"profile={prof.id} hwnd={h} findall={after.findall_count} " f"missing={after.markers_missing} notes={after.notes}", )