Summary
monitor:<index> capture uses the monitor bounds from System.Windows.Forms.Screen.AllScreens, but that PowerShell process is DPI-unaware, so it returns logical (DPI-scaled) bounds. gdigrab works in physical pixels. On any display scaled above 100%, monitor:N therefore captures only a cropped top-left portion of the screen.
Where
src/utils/monitors.ts PS_SCRIPT / getMonitors. Note src/utils/windows.ts already calls SetProcessDpiAwarenessContext(-4) for window-bounds enumeration; monitors.ts does not.
Live evidence (150% scaled display)
full screenshot -> 1920x1200 (physical, correct).
monitor:0 screenshot -> 1280x800 (logical) -> captures only the top-left 1280x800 of the 1920x1200 physical screen.
- Verified directly:
- DPI-unaware
Screen.AllScreens.Bounds -> 1280x800
- DPI-aware (
SetProcessDpiAwarenessContext(-4)) -> 1920x1200
Suggested fix
Make the monitor-enumeration PowerShell per-monitor-DPI-aware (call SetProcessDpiAwarenessContext(-4) before reading Screen.AllScreens), exactly as windows.ts already does, so monitor bounds are physical pixels that match gdigrab. Add a regression note in the local capture harness.
Summary
monitor:<index>capture uses the monitor bounds fromSystem.Windows.Forms.Screen.AllScreens, but that PowerShell process is DPI-unaware, so it returns logical (DPI-scaled) bounds. gdigrab works in physical pixels. On any display scaled above 100%,monitor:Ntherefore captures only a cropped top-left portion of the screen.Where
src/utils/monitors.tsPS_SCRIPT/getMonitors. Notesrc/utils/windows.tsalready callsSetProcessDpiAwarenessContext(-4)for window-bounds enumeration;monitors.tsdoes not.Live evidence (150% scaled display)
fullscreenshot -> 1920x1200 (physical, correct).monitor:0screenshot -> 1280x800 (logical) -> captures only the top-left 1280x800 of the 1920x1200 physical screen.Screen.AllScreens.Bounds->1280x800SetProcessDpiAwarenessContext(-4)) ->1920x1200Suggested fix
Make the monitor-enumeration PowerShell per-monitor-DPI-aware (call
SetProcessDpiAwarenessContext(-4)before readingScreen.AllScreens), exactly aswindows.tsalready does, so monitor bounds are physical pixels that match gdigrab. Add a regression note in the local capture harness.