Skip to content

Conversation

@Memphizzz
Copy link

Summary of the Pull Request

Use DPI-unaware context when positioning overlay windows to match the coordinate space from the C++ backend.

The FancyZones editor overlay windows were incorrectly positioned on secondary monitors when using different DPI scaling (e.g., 125%/150%/125%). Zones appeared shifted or clipped because they extended past monitor edges.

PR Checklist

Detailed Description of the Pull Request / Additional comments

Root Cause

The C++ backend uses a DPI-unaware thread to get virtual screen coordinates, but the WPF editor (PerMonitorV2 DPI-aware) interpreted these coordinates with DPI scaling applied, causing misalignment on non-primary monitors.

Fix

  • EditorParameters.cpp: Use consistent virtual coordinates for all monitor properties (removed DPIAware::Convert that was only applied to dimensions)
  • Monitor.cs: Reposition overlay windows using DPI-unaware context after HWND creation, matching the coordinate space from C++ backend
  • NativeMethods.cs: Added SetWindowPositionDpiUnaware() using SetThreadDpiAwarenessContext to temporarily switch DPI awareness

Validation Steps Performed

Manually tested on 3-monitor setup with 125%/150%/125% DPI scaling - overlays now correctly cover each monitor's work area.


🤖 This fix was developed with Claude Code after 6 hours of debugging DPI coordinate systems together.

Use DPI-unaware context when positioning overlay windows to match the coordinate space from the C++ backend.

Co-Authored-By: Claude <[email protected]>
@Memphizzz
Copy link
Author

@microsoft-github-policy-service agree

@lei9444
Copy link
Contributor

lei9444 commented Jan 4, 2026

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes FancyZones editor overlay window positioning issues on multi-monitor setups with different DPI scaling. The core problem was that the C++ backend uses DPI-unaware coordinates while the WPF editor interprets them with DPI scaling, causing misalignment on non-primary monitors.

Key Changes:

  • Removed inconsistent DPI conversion that was only applied to monitor dimensions
  • Added DPI-unaware window positioning function in C# to match coordinate space from C++ backend
  • Updated window positioning logic to use DPI-unaware context after HWND creation

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
EditorParameters.cpp Removed DPIAware::Convert for monitor dimensions, ensuring all monitor properties use consistent DPI-unaware coordinates from the dpiUnawareThread
NativeMethods.cs Added SetWindowPositionDpiUnaware() utility that temporarily switches to DPI-unaware context for window positioning via P/Invoke
Monitor.cs Updated constructor and Scale() method to use DPI-unaware positioning, added SourceInitialized event handler to reposition windows after HWND creation

return;
}
monitorInfoUnaware.cbSize = sizeof(monitorInfoUnaware);
GetMonitorInfo(monitor, &monitorInfoUnaware);
Copy link

Copilot AI Jan 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The return value of GetMonitorInfo should be checked. If it fails, the monitorInfoUnaware structure will contain uninitialized data, leading to incorrect monitor dimensions being passed to the editor. Consider checking the return value and continuing to the next monitor if it fails, similar to how GetScreenDPIForMonitor is checked on line 187.

Copilot uses AI. Check for mistakes.
IntPtr oldContext = SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_UNAWARE);
try
{
SetWindowPos(helper, IntPtr.Zero, x, y, width, height, SWP_NOZORDER | SWP_NOACTIVATE);
Copy link

Copilot AI Jan 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The return value of SetWindowPos should be checked. If it fails, the window positioning will silently fail and the overlay may still be mispositioned. Consider checking the return value and logging a warning or error if the operation fails, similar to how error handling is done elsewhere in the codebase (e.g., checking SetLastError when the function returns false).

Copilot uses AI. Check for mistakes.
@lei9444
Copy link
Contributor

lei9444 commented Jan 8, 2026

I committed a fix that scales monitor dimensions by the DPI factor so the editor shows the actual physical resolution.
Before fix
image

After fix
image

@lei9444
Copy link
Contributor

lei9444 commented Jan 8, 2026

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

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.

FancyZones - Not Capturing full screen FancyZones not using full screen

2 participants