diff --git a/catser/window_manager.py b/catser/window_manager.py index d99bd6a..4c4585d 100644 --- a/catser/window_manager.py +++ b/catser/window_manager.py @@ -244,6 +244,8 @@ class WindowManager: def get_work_area() -> Tuple[int, int, int, int]: """ Returns desktop work area (left, top, right, bottom) excluding the taskbar. + NOTE: This only covers the *primary* monitor's work area. + Use get_virtual_desktop_bounds() for full multi-monitor extent. """ SPI_GETWORKAREA = 0x0030 rect = wintypes.RECT() @@ -252,3 +254,32 @@ class WindowManager: # Fallback to full screen w, h = WindowManager.get_screen_dimensions() return (0, 0, w, h) + + @staticmethod + def get_virtual_desktop_bounds() -> Tuple[int, int, int, int]: + """ + Returns the bounding rectangle of the full virtual desktop spanning ALL monitors. + + On a single-monitor system this equals get_screen_dimensions(). + On multi-monitor systems it covers every display, including those with + negative coordinates (monitors left of / above the primary). + + Returns: + (left, top, right, bottom) in virtual-desktop pixel coordinates. + """ + SM_XVIRTUALSCREEN = 76 # Left edge of virtual desktop + SM_YVIRTUALSCREEN = 77 # Top edge of virtual desktop + SM_CXVIRTUALSCREEN = 78 # Total width of virtual desktop + SM_CYVIRTUALSCREEN = 79 # Total height of virtual desktop + + vx = user32.GetSystemMetrics(SM_XVIRTUALSCREEN) + vy = user32.GetSystemMetrics(SM_YVIRTUALSCREEN) + vw = user32.GetSystemMetrics(SM_CXVIRTUALSCREEN) + vh = user32.GetSystemMetrics(SM_CYVIRTUALSCREEN) + + if vw == 0 or vh == 0: + # GetSystemMetrics failed – fall back to primary screen + w, h = WindowManager.get_screen_dimensions() + return (0, 0, w, h) + + return (vx, vy, vx + vw, vy + vh)