import win32gui import win32con import win32api import threading from typing import Callable def get_active_window() -> str: """Get the currently active window title on Windows""" try: hwnd = win32gui.GetForegroundWindow() return win32gui.GetWindowText(hwnd) or "Unknown Window" except: return "Error getting window title" def register_session_listener(callback: Callable[[str], None]) -> None: """Register a callback for Windows session lock/unlock events""" def session_event_handler(hwnd, msg, wparam, lparam): # Check if the constant exists before using it try: if msg == win32con.WM_WTSSESSION_CHANGE: if wparam == getattr(win32con, 'WTS_SESSION_LOCK', 0x1): callback("locked") elif wparam == getattr(win32con, 'WTS_SESSION_UNLOCK', 0x2): callback("unlocked") except AttributeError: # Some versions of pywin32 might not have these constants # Use numeric values as fallback WM_WTSSESSION_CHANGE = 0x02B1 WTS_SESSION_LOCK = 0x1 WTS_SESSION_UNLOCK = 0x2 if msg == WM_WTSSESSION_CHANGE: if wparam == WTS_SESSION_LOCK: callback("locked") elif wparam == WTS_SESSION_UNLOCK: callback("unlocked") 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 # Corrected CreateWindow call with all required parameters hwnd = win32gui.CreateWindow( wndclass.lpszClassName, # lpClassName "Session Watcher", # lpWindowName 0, # dwStyle 0, # x 0, # y 0, # nWidth 0, # nHeight 0, # hWndParent 0, # hMenu hinst, # hInstance None # lParam ) # Register for session notifications try: from win32ts import WTSRegisterSessionNotification WTSRegisterSessionNotification(hwnd, 1) # NOTIFY_FOR_THIS_SESSION except ImportError: # pywin32 might not have win32ts on all systems pass # Start message loop win32gui.PumpMessages() # Run in a separate thread 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 # Convert milliseconds to seconds