Target Repository:
WinStasis(winst)
Topic: Multi-Monitor DPI Awareness, Win32 Coordinate Virtualization, andWINDOWPLACEMENTDrift
Status: Identified Issue (Deferred / Backlogged for Future Milestone)
Severity: High (Affects multi-monitor systems with heterogeneous DPI scaling)
An audit of WinStasis confirms that WinStasis currently suffers from the Windows DPI Virtualization Trap on multi-monitor workstations with mixed scaling factors (e.g., 4K Primary Display at 150% DPI + 1080p Secondary Display at 100% DPI).
WinStasis.csprojdoes not embed anapp.manifestdeclaring Windows DPI awareness.Program.csdoes not callSetProcessDpiAwarenessContext.- By default, the .NET runtime defaults the
winst.exeprocess to DPI Unaware or System DPI Aware.
When winst.exe runs in a DPI-unaware or System-DPI-aware state on a multi-monitor system with different scale factors:
- In
WindowsEnvironmentAdapter.cs,winstcalls Win32GetWindowPlacementto capturercNormalPosition(X,Y,Width,Height). - When querying a window located on a secondary display with a different DPI scale factor, Windows User32 virtualizes and rescales the rectangle coordinates to match the primary display's scaling.
- When
winst restorelater passes these virtualized coordinates toSetWindowPlacement, the window will either shrink, expand exponentially, or offset away from its original physical position.
- In
WindowRestorer.cs,ClampToNearestMonitor()calls_env.GetWorkAreaForRect()which invokesMonitorFromRectandGetMonitorInfo. - Because the input rectangle is virtualized,
MonitorFromRectcan resolve to the wrong physical monitor handle (HMONITOR). monitorInfo.rcWorkreturns virtualized screen bounds, causing boundary clamping to snap windows to incorrect display coordinates.
When scheduling the fix for WinStasis, the remediation requires two simple steps:
Create an application manifest in the WinStasis/ project folder:
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="WinStasis.app"/>
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/pm</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2, PerMonitor</dpiAwareness>
</windowsSettings>
</application>
</assembly>Add the <ApplicationManifest> property to <PropertyGroup>:
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0-windows10.0.19041.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AssemblyName>winst</AssemblyName>
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>This issue is documented in the WinStasis research ledger and will be implemented when multi-monitor topology features are tackled.