fix: forțează SetForegroundWindow prin ALT-key pentru anti focus-stealing
pygetwindow.activate() raporta succes dar Windows refuza silent ridicarea ferestrei TS (confirmat în audit: window_focused cu titlul corect, dar screenshot-ul manual tot prindea app-ul de deasupra). Trucul standard: keybd_event(ALT) resetează focus-lock-ul, apoi SetForegroundWindow via ctypes pe hwnd direct. Fallback la win.activate() dacă lipsește _hWnd. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user