initial 2
This commit is contained in:
@@ -1,90 +1,34 @@
|
||||
import win32gui
|
||||
import win32process
|
||||
import win32con
|
||||
import win32api
|
||||
import threading
|
||||
from typing import Callable
|
||||
import psutil
|
||||
from .base import PlatformBase, WindowInfo
|
||||
|
||||
|
||||
def get_active_window() -> str:
|
||||
"""Returns a string like 'YouTube - Chrome (chrome.exe)'"""
|
||||
try:
|
||||
hwnd = win32gui.GetForegroundWindow()
|
||||
title = win32gui.GetWindowText(hwnd) or "Unknown Window"
|
||||
|
||||
# Get process name
|
||||
_, pid = win32process.GetWindowThreadProcessId(hwnd)
|
||||
class WindowsPlatform(PlatformBase):
|
||||
def get_active_window(self) -> WindowInfo:
|
||||
try:
|
||||
proc = psutil.Process(pid)
|
||||
exe_name = proc.name()
|
||||
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
|
||||
exe_name = "unknown.exe"
|
||||
hwnd = win32gui.GetForegroundWindow()
|
||||
if not hwnd:
|
||||
return WindowInfo(title="", process_name="")
|
||||
|
||||
return f"{title} ({exe_name})"
|
||||
except Exception:
|
||||
return "Error getting window info"
|
||||
# Получаем заголовок окна
|
||||
title = win32gui.GetWindowText(hwnd).strip()
|
||||
|
||||
# Получаем PID процесса
|
||||
_, pid = win32process.GetWindowThreadProcessId(hwnd)
|
||||
|
||||
def register_session_listener(callback: Callable[[str], None]) -> None:
|
||||
"""Register a callback for Windows session lock/unlock events"""
|
||||
if pid == 0:
|
||||
return WindowInfo(title=title, process_name="")
|
||||
|
||||
def session_event_handler(hwnd, msg, wparam, lparam):
|
||||
# Fallback numeric constants
|
||||
WM_WTSSESSION_CHANGE = 0x02B1
|
||||
WTS_SESSION_LOCK = 0x1
|
||||
WTS_SESSION_UNLOCK = 0x2
|
||||
# Получаем имя исполняемого файла процесса
|
||||
try:
|
||||
process = psutil.Process(pid)
|
||||
process_name = process.name()
|
||||
except (psutil.NoSuchProcess, psutil.AccessDenied):
|
||||
process_name = ""
|
||||
|
||||
if msg == WM_WTSSESSION_CHANGE:
|
||||
if wparam == WTS_SESSION_LOCK:
|
||||
callback("locked")
|
||||
elif wparam == WTS_SESSION_UNLOCK:
|
||||
callback("unlocked")
|
||||
return WindowInfo(title=title, process_name=process_name)
|
||||
|
||||
return win32gui.DefWindowProc(hwnd, msg, wparam, lparam)
|
||||
|
||||
def run_message_loop():
|
||||
hinst = win32api.GetModuleHandle(None)
|
||||
wndclass = win32gui.WNDCLASS()
|
||||
wndclass.hInstance = hinst
|
||||
wndclass.lpszClassName = "SessionWatcher"
|
||||
wndclass.lpfnWndProc = session_event_handler
|
||||
|
||||
try:
|
||||
win32gui.RegisterClass(wndclass)
|
||||
except:
|
||||
pass # Already registered
|
||||
|
||||
hwnd = win32gui.CreateWindow(
|
||||
wndclass.lpszClassName,
|
||||
"Session Watcher",
|
||||
0, 0, 0, 0, 0,
|
||||
0, 0, hinst, None
|
||||
)
|
||||
|
||||
# Register for session notifications
|
||||
try:
|
||||
from win32ts import WTSRegisterSessionNotification
|
||||
WTSRegisterSessionNotification(hwnd, 1)
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
win32gui.PumpMessages()
|
||||
|
||||
thread = threading.Thread(target=run_message_loop, daemon=True)
|
||||
thread.start()
|
||||
|
||||
|
||||
def get_idle_time() -> int:
|
||||
"""Get the system idle time in seconds on Windows"""
|
||||
from ctypes import Structure, windll, c_uint, sizeof, byref
|
||||
|
||||
class LASTINPUTINFO(Structure):
|
||||
_fields_ = [('cbSize', c_uint), ('dwTime', c_uint)]
|
||||
|
||||
lastInputInfo = LASTINPUTINFO()
|
||||
lastInputInfo.cbSize = sizeof(lastInputInfo)
|
||||
windll.user32.GetLastInputInfo(byref(lastInputInfo))
|
||||
|
||||
millis = windll.kernel32.GetTickCount() - lastInputInfo.dwTime
|
||||
return millis // 1000
|
||||
except Exception:
|
||||
# В случае ошибки (например, недоступно окно) — возвращаем пустые данные
|
||||
return WindowInfo(title="", process_name="")
|
||||
Reference in New Issue
Block a user