Fix SetupWindowForScreen using wrong DPI source#30
Conversation
SetupWindowForScreen was using PresentationSource.FromVisual(this) which returns the DPI of the monitor the window is currently on, not the target screen's DPI. This is incorrect when positioning onto a different monitor. Replaced with GetDpiForScreen(screen) which correctly queries the target monitor's DPI via GetDpiForMonitor P/Invoke.
There was a problem hiding this comment.
Pull request overview
This PR fixes a DPI handling bug in multi-monitor setups where SetupWindowForScreen was incorrectly using the current window's monitor DPI instead of the target screen's DPI. The fix ensures windows are correctly positioned on monitors with different DPI scaling settings.
Changes:
- Replaced
PresentationSource.FromVisual(this)DPI retrieval withGetDpiForScreen(screen)inSetupWindowForScreento query the target monitor's actual DPI - Added
DpiChangedevent handler for monitor windows to dynamically handle runtime DPI changes
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| window.Left = screen.WorkingArea.X / ctx.DpiScaleX; | ||
| window.Top = screen.WorkingArea.Y / ctx.DpiScaleY; | ||
| window.Width = screen.WorkingArea.Width / ctx.DpiScaleX; | ||
| window.Height = screen.WorkingArea.Height / ctx.DpiScaleY; |
There was a problem hiding this comment.
The window repositioning and resizing in the DpiChanged handler should include a guard to prevent unnecessary updates when values haven't changed significantly. The main window's OnDpiChanged (lines 601-603) and the Loaded handler (lines 1125-1126) both check if the new position/size differs significantly before updating. Without this guard, there's a potential for unnecessary layout cycles or edge-case infinite loops if setting the window properties somehow triggers another DPI change event.
SetupWindowForScreen was using PresentationSource.FromVisual(this) to get DPI, which returns the DPI of the monitor the window is currently on - not the target screen. Replaced with GetDpiForScreen(screen) which correctly queries the target monitor DPI via GetDpiForMonitor P/Invoke.