From 0958e79cf937ee55f714ed2a18d86ee22652f94a Mon Sep 17 00:00:00 2001 From: Emmanuel Hansen Date: Thu, 9 Oct 2025 12:37:35 +0000 Subject: [PATCH] Win32 - Fix margins and nc hit test for caption buttons in extend to client windows (#19773) * win32 - fix margins and nc hit test for caption buttons in extend to client windows * use unsused scaling variable --- .../WindowImpl.CustomCaptionProc.cs | 29 ++++++++++++++++--- src/Windows/Avalonia.Win32/WindowImpl.cs | 28 ++++++++++++++++-- 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/src/Windows/Avalonia.Win32/WindowImpl.CustomCaptionProc.cs b/src/Windows/Avalonia.Win32/WindowImpl.CustomCaptionProc.cs index e81c430eb7..fc7fe731d0 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.CustomCaptionProc.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.CustomCaptionProc.cs @@ -17,13 +17,34 @@ namespace Avalonia.Win32 // Get the window rectangle. GetWindowRect(hWnd, out var rcWindow); + var scaling = (uint)(RenderScaling * StandardDpi); + var relativeScaling = RenderScaling / PrimaryScreenRenderScaling; + // Get the frame rectangle, adjusted for the style without a caption. var rcFrame = new RECT(); - AdjustWindowRectEx(ref rcFrame, (uint)(WindowStyles.WS_OVERLAPPEDWINDOW & ~WindowStyles.WS_CAPTION), false, 0); - var borderThickness = new RECT(); - - AdjustWindowRectEx(ref borderThickness, (uint)GetStyle(), false, 0); + if (Win32Platform.WindowsVersion < PlatformConstants.Windows10_1607) + { + AdjustWindowRectEx(ref rcFrame, (uint)(WindowStyles.WS_OVERLAPPEDWINDOW & ~WindowStyles.WS_CAPTION), false, 0); + + rcFrame.top = (int)(rcFrame.top * relativeScaling); + rcFrame.right = (int)(rcFrame.right * relativeScaling); + rcFrame.left = (int)(rcFrame.left * relativeScaling); + rcFrame.bottom = (int)(rcFrame.bottom * relativeScaling); + + AdjustWindowRectEx(ref borderThickness, (uint)GetStyle(), false, 0); + + borderThickness.top = (int)(borderThickness.top * relativeScaling); + borderThickness.right = (int)(borderThickness.right * relativeScaling); + borderThickness.left = (int)(borderThickness.left * relativeScaling); + borderThickness.bottom = (int)(borderThickness.bottom * relativeScaling); + } + else + { + AdjustWindowRectExForDpi(ref rcFrame, WindowStyles.WS_OVERLAPPEDWINDOW & ~WindowStyles.WS_CAPTION, false, 0, scaling); + AdjustWindowRectExForDpi(ref borderThickness, GetStyle(), false, 0, scaling); + } + borderThickness.left *= -1; borderThickness.top *= -1; diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index c85b434761..ac230744bc 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -1100,8 +1100,30 @@ namespace Avalonia.Win32 RECT borderThickness = new RECT(); RECT borderCaptionThickness = new RECT(); - AdjustWindowRectEx(ref borderCaptionThickness, (uint)(GetStyle()), false, 0); - AdjustWindowRectEx(ref borderThickness, (uint)(GetStyle() & ~WindowStyles.WS_CAPTION), false, 0); + var scaling = (uint)(RenderScaling * StandardDpi); + var relativeScaling = RenderScaling / PrimaryScreenRenderScaling; + + if (Win32Platform.WindowsVersion < PlatformConstants.Windows10_1607) + { + AdjustWindowRectEx(ref borderCaptionThickness, (uint)GetStyle(), false, 0); + AdjustWindowRectEx(ref borderThickness, (uint)(GetStyle() & ~WindowStyles.WS_CAPTION), false, 0); + + borderCaptionThickness.top = (int)(borderCaptionThickness.top * relativeScaling); + borderCaptionThickness.right = (int)(borderCaptionThickness.right * relativeScaling); + borderCaptionThickness.left = (int)(borderCaptionThickness.left * relativeScaling); + borderCaptionThickness.bottom = (int)(borderCaptionThickness.bottom * relativeScaling); + + borderThickness.top = (int)(borderThickness.top * relativeScaling); + borderThickness.right = (int)(borderThickness.right * relativeScaling); + borderThickness.left = (int)(borderThickness.left * relativeScaling); + borderThickness.bottom = (int)(borderThickness.bottom * relativeScaling); + } + else + { + AdjustWindowRectExForDpi(ref borderCaptionThickness, GetStyle(), false, 0, scaling); + AdjustWindowRectExForDpi(ref borderThickness, GetStyle() & ~WindowStyles.WS_CAPTION, false, 0, scaling); + } + borderThickness.left *= -1; borderThickness.top *= -1; borderCaptionThickness.left *= -1; @@ -1132,7 +1154,7 @@ namespace Avalonia.Win32 if (WindowState == WindowState.Maximized) { _extendedMargins = new Thickness(0, (borderCaptionThickness.top - borderThickness.top) / RenderScaling, 0, 0); - _offScreenMargin = new Thickness(borderThickness.left / PrimaryScreenRenderScaling, borderThickness.top / PrimaryScreenRenderScaling, borderThickness.right / PrimaryScreenRenderScaling, borderThickness.bottom / PrimaryScreenRenderScaling); + _offScreenMargin = new Thickness(borderThickness.left / RenderScaling, borderThickness.top / RenderScaling, borderThickness.right / RenderScaling, borderThickness.bottom / RenderScaling); } else {