diff --git a/src/atm/main.py b/src/atm/main.py index d43778b..e2e3483 100644 --- a/src/atm/main.py +++ b/src/atm/main.py @@ -202,6 +202,12 @@ def _focus_window_by_title(needle: str) -> str | None: Returnează titlul găsit sau None (niciun match, Win32 a refuzat activate, sau `pygetwindow` lipsește — caz normal pe Linux/WSL unde rulează doar testele). + + pygetwindow.activate() folosește SetForegroundWindow, care Windows îl + refuză silent când procesul apelant nu e cel care deține focus-ul + (protecția anti focus-stealing introdusă în Win2000). Trucul standard: + trimiți un ALT press/release ca să resetezi lock-ul, apoi restore + + SetForegroundWindow prin ctypes pe hwnd direct. """ try: import pygetwindow as gw # type: ignore[import-untyped] @@ -213,10 +219,22 @@ def _focus_window_by_title(needle: str) -> str | None: if not matches: return None win = matches[0] + hwnd = getattr(win, "_hWnd", None) + if hwnd is None: + try: + win.activate() + return win.title + except Exception: + return None try: - if win.isMinimized: - win.restore() - win.activate() + import ctypes + user32 = ctypes.windll.user32 + # VK_MENU=0x12 (ALT), KEYEVENTF_KEYUP=0x02 — unlocks focus protection. + user32.keybd_event(0x12, 0, 0, 0) + user32.keybd_event(0x12, 0, 0x02, 0) + user32.ShowWindow(hwnd, 9) # SW_RESTORE + user32.BringWindowToTop(hwnd) + user32.SetForegroundWindow(hwnd) return win.title except Exception: return None