Skip to content

Fix DPI change handling for additional monitor windows#28

Draft
Copilot wants to merge 1 commit intomasterfrom
copilot/file-dpi-issues-separately
Draft

Fix DPI change handling for additional monitor windows#28
Copilot wants to merge 1 commit intomasterfrom
copilot/file-dpi-issues-separately

Conversation

Copy link
Contributor

Copilot AI commented Feb 11, 2026

Additional monitor windows created via CreateMonitorWindow() don't respond to runtime DPI changes, causing incorrect rendering and hole-punch positioning when users move windows between monitors with different scaling or change system DPI settings.

Changes

  • Added DpiChanged event handler to additional monitor windows in CreateMonitorWindow() that updates ctx.DpiScaleX/Y and repositions window
  • Ensures hole-punch effect in ApplyHolePunchEffect() uses current DPI values from MonitorWindowContext

Root Cause

Main window has OnDpiChanged() override (lines 585-619) that updates _dpiScaleX/Y and repositions. Additional monitor windows had no equivalent handler, leaving their ctx.DpiScaleX/Y frozen at creation-time values.

// Before: MonitorWindowContext DPI values never updated
CreateMonitorWindow(screen); // Sets ctx.DpiScaleX/Y once
// User moves window to different DPI → ctx values stale

// After: DpiChanged handler updates context
monitorWindow.DpiChanged += (s, e) => {
    ctx.DpiScaleX = e.NewDpi.DpiScaleX;
    ctx.DpiScaleY = e.NewDpi.DpiScaleY;
    // Reposition window...
};

Affects multi-monitor setups where monitors have different scaling factors or users change DPI at runtime.

Original prompt

Fantastic. Let's go and file issues for both one and two separately using the GitHub CLI and then assign those to Copilot in the cloud and let it work on them.

[Chronological Review] 1. User initiated a code review via /review command, specifically requesting a dual-model review (Opus + Codex) of DPI-related code and spec docs in the WindowsEdgeLight repository 2. An explore agent was dispatched to find all DPI-related files in the repo 3. The main DPI spec doc, source code, manifest, and PR9 doc were read in full 4. Specific sections of MainWindow.xaml.cs were read (DPI declarations, CreateMonitorWindow, GetDpiForScreen, SetupWindowForScreen, OnDpiChanged, HandleMouseMove, MoveToNextMonitor) 5. Two background code-review agents were launched in parallel: one with claude-opus-4.6 and one with gpt-5.1-codex 6. Codex completed successfully with 2 issues found 7. Opus timed out after 633s with no response, was retried twice more (as code-review and general-purpose agents) with no response 8. A Sonnet 4.5 general-purpose agent was used as the second reviewer instead of Opus 9. Sonnet 4.5 completed successfully with a detailed analysis confirming the same 2 bugs Codex found, plus confirming 4 other concerns as non-issues 10. Final consensus results were presented to the user

[Intent Mapping]

  • User: "Take a look at the docs on DPI and use both Opus and Codex to do a complete review of the spec for our DPI work and the correctness of the code and only tell me issues that both models agree on."
  • User checked in with "how is it going" while waiting for background agents

[Technical Inventory]

  • WPF app with PerMonitorV2 DPI awareness
  • Win32 P/Invoke: GetDpiForMonitor, MonitorFromPoint, SetWindowPos
  • .NET Screen.AllScreens / Screen.WorkingArea (physical pixels)
  • WPF DIPs (Device Independent Pixels) coordinate system
  • PresentationSource.TransformToDevice for DPI detection
  • Window.OnDpiChanged override for runtime DPI changes
  • Low-level mouse hook (WH_MOUSE_LL) for hole-punch effect
  • app.manifest: PerMonitorV2 + true/PM dpi awareness
  • csproj: ApplicationHighDpiMode PerMonitorV2

[Code Archaeology]

  • MainWindow.xaml.cs (~1310+ lines, 49.9KB)
    • Lines 29-31: _dpiScaleX/_dpiScaleY instance fields
    • Lines 45-58: MonitorWindowContext class with DpiScaleX/DpiScaleY properties
    • Lines 88-95: Win32 DPI API declarations (MonitorFromPoint, GetDpiForMonitor, MDT_EFFECTIVE_DPI, MONITOR_DEFAULTTONEAREST)
    • Lines 275-297: SetupWindowForScreen - gets DPI from PresentationSource, positions main window
    • Lines 367-441: HandleMouseMove - dispatches hole-punch for main + additional windows
    • Lines 444-458: ApplyHolePunchEffect - coordinate conversion using per-window DPI
    • Lines 585-619: OnDpiChanged override - updates _dpiScaleX/Y, repositions main window
    • Lines 882-940: MoveToNextMonitor - SetWindowPos + DPI-aware positioning
    • Lines 948-982: ToggleAllMonitors / ShowOnAllMonitors
    • Lines 993-1151: CreateMonitorWindow - per-monitor DPI, Loaded handler one-time correction
    • Lines 1153-1181: UpdateMonitorGeometry
    • Lines 1265-1295: GetDpiForScreen - Win32 API calls to get per-monitor DPI scale

[Progress Assessment]

  • COMPLETE: All DPI files explored and catalogued
  • COMPLETE: Full source code read for DPI-related sections
  • COMPLETE: Codex review (2 issues found)
  • FAILED: Opus review (3 attempts, no response)
  • COMPLETE: Sonnet 4.5 review as substitute (2 bugs + 4 non-bugs confirmed)
  • COMPLETE: Consensus analysis presented to user

[Context Validation]
All critical information captured. The review is complete and findings delivered.

[Recent Commands Analysis]
The most recent operations were:

  1. Sonnet 4.5 general-purpose agent completed with detailed findings
  2. Final synthesis of Codex + Sonnet 4.5 results presented to user
  3. User has received the final consensus report
1. Conversation Overview: - Primary Objectives: User requested "/review" — specifically: "Take a look at the docs on DPI and use both Opus and Codex to do a complete review of the spec for our DPI work and the correctness of the code and only tell me issues that both models agree on." - Session Context: A code review of the DPI (display scaling) implementation in the WindowsEdgeLight WPF application. The user wanted a high-confidence review by requiring agreement between two different AI models before surfacing any issue. - User Intent Evolution: Straightforward single request. User checked in once ("how is it going") while waiting for background agents. No scope changes.
  1. Technical Foundation:
    • WPF (.NET 10.0): Desktop application with transparent overlay windows showing edge-light effects on monitors
    • PerMonitorV2 DPI Awareness: Declared in both app.manifest (<dpiAwareness>PerMonitorV2</dpiAwareness>) and .csproj (<ApplicationHighDpiMode>PerMonitorV2</ApplicationHighDpiMode>)
    • Win32 P/Invoke APIs: GetDpiForMonitor (shcore.dll), MonitorFromPoint...

Created from Copilot CLI via the copilot delegate command.


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI changed the title [WIP] File issues for DPI-related code review Fix DPI change handling for additional monitor windows Feb 11, 2026
Copilot AI requested a review from shanselman February 11, 2026 23:25
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.

2 participants