Skip to content

docs(dpi): document non-guaranteed per-monitor DPI awareness - #28

Merged
aksOps merged 4 commits into
mainfrom
claude/serene-murdock-7c18d0
Aug 13, 2026
Merged

docs(dpi): document non-guaranteed per-monitor DPI awareness#28
aksOps merged 4 commits into
mainfrom
claude/serene-murdock-7c18d0

Conversation

@aksOps

@aksOps aksOps commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

What changed

Documentation-only correction across AGENTS.md, README.md, and two codebase reference docs (since removed from the repository). No source or behavior change; generated SnipIT.ps1 untouched.

Why

The docs claimed SnipIT is per-monitor DPI aware with accurate mixed-DPI capture. Investigation (2026-08-13) proved the startup SetProcessDpiAwarenessContext(PER_MONITOR_AWARE_V2) call (src/20-Native.ps1, result piped to Out-Null) can silently fail:

  • Empirically confirmed: under a pwsh host where process DPI awareness was already set, the call returns False with ERROR_ACCESS_DENIED (Win32 error 5) and the process stays SYSTEM aware.
  • Mechanism is not the pwsh.exe manifest — its RT_MANIFEST declares no dpiAware entry, and a bare unmanifested exe starts DPI-unaware on the same machine. On the affected machine, injected software (Citrix App Protection, ctxapclient64.dll) pre-loads WinForms/WPF into every pwsh at startup; their initialization sets SYSTEM awareness before any script statement, which locks it.
  • Consequence when locked: GetDpiForMonitor reports the system DPI for every monitor (so Get-SnipMonitorDescriptors shows uniform DPI on mixed-DPI hardware) and captures on non-system-DPI monitors go through DWM virtualization (rescaled, not native pixels). Uniform-DPI setups are unaffected.
  • On clean machines the call likely succeeds — SnipIT's ordering is correct (PMv2 request runs before the first window is created) — so docs now say per-monitor DPI is requested, not guaranteed.

Reviewer notes

  • SetThreadDpiAwarenessContext(PMv2) was verified to still succeed per-thread even when process awareness is locked; it is recorded in CONCERNS.md as the candidate escape hatch for capture paths. Behavior remediation (assert+log the return value, per-thread PMv2 around capture) is deliberately left for a follow-up with mixed-DPI tests, per the no-behavior-change-without-tests rule.
  • git diff --exit-code -- SnipIT.ps1 is clean by construction (no src//xaml/ edits, no rebuild needed).

aksOps and others added 4 commits July 23, 2026 21:50
SetProcessDpiAwarenessContext(PER_MONITOR_AWARE_V2) at startup discards
its return value and fails with ERROR_ACCESS_DENIED (Win32 error 5) when
process DPI awareness was already set before script code ran — verified
2026-08-13 under a host where injected software (Citrix App Protection)
pre-loads WinForms/WPF into every pwsh, leaving it SYSTEM aware. In that
state GetDpiForMonitor reports the system DPI for every monitor and
mixed-DPI captures are DWM-virtualized.

Correct AGENTS.md, README.md, and .planning docs to state the request-
not-guarantee reality. Note pwsh.exe's manifest declares no dpiAware
entry, and SetThreadDpiAwarenessContext(PMv2) still succeeds per-thread
as the candidate escape hatch. Docs only; no behavior change, generated
SnipIT.ps1 untouched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@aksOps
aksOps enabled auto-merge (squash) August 13, 2026 06:26
@aksOps
aksOps merged commit aceb70f into main Aug 13, 2026
12 checks passed
@aksOps
aksOps deleted the claude/serene-murdock-7c18d0 branch August 13, 2026 06:45
aksOps added a commit that referenced this pull request Aug 14, 2026
* refactor(preview): use native WPF layout

* test(preview): align checks with native WPF

* fix(preview): prevent More label clipping

* docs(dpi): document non-guaranteed per-monitor DPI awareness

SetProcessDpiAwarenessContext(PER_MONITOR_AWARE_V2) at startup discards
its return value and fails with ERROR_ACCESS_DENIED (Win32 error 5) when
process DPI awareness was already set before script code ran — verified
2026-08-13 under a host where injected software (Citrix App Protection)
pre-loads WinForms/WPF into every pwsh, leaving it SYSTEM aware. In that
state GetDpiForMonitor reports the system DPI for every monitor and
mixed-DPI captures are DWM-virtualized.

Correct AGENTS.md, README.md, and .planning docs to state the request-
not-guarantee reality. Note pwsh.exe's manifest declares no dpiAware
entry, and SetThreadDpiAwarenessContext(PMv2) still succeeds per-thread
as the candidate escape hatch. Docs only; no behavior change, generated
SnipIT.ps1 untouched.


---------
aksOps added a commit that referenced this pull request Aug 14, 2026
* refactor(preview): use native WPF layout

* test(preview): align checks with native WPF

* fix(preview): prevent More label clipping

* docs(dpi): document non-guaranteed per-monitor DPI awareness

SetProcessDpiAwarenessContext(PER_MONITOR_AWARE_V2) at startup discards
its return value and fails with ERROR_ACCESS_DENIED (Win32 error 5) when
process DPI awareness was already set before script code ran — verified
2026-08-13 under a host where injected software (Citrix App Protection)
pre-loads WinForms/WPF into every pwsh, leaving it SYSTEM aware. In that
state GetDpiForMonitor reports the system DPI for every monitor and
mixed-DPI captures are DWM-virtualized.

Correct AGENTS.md, README.md, and .planning docs to state the request-
not-guarantee reality. Note pwsh.exe's manifest declares no dpiAware
entry, and SetThreadDpiAwarenessContext(PMv2) still succeeds per-thread
as the candidate escape hatch. Docs only; no behavior change, generated
SnipIT.ps1 untouched.


---------
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant