initial 2

This commit is contained in:
Mikan
2026-03-10 01:40:10 +03:00
parent 346ea77fd2
commit 6946b8fb50
24 changed files with 370 additions and 1602 deletions

View File

@@ -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="")