diff --git a/src/UniGetUI.Avalonia/Views/MainWindow.axaml.cs b/src/UniGetUI.Avalonia/Views/MainWindow.axaml.cs index df08f58aa7..15d1a11b53 100644 --- a/src/UniGetUI.Avalonia/Views/MainWindow.axaml.cs +++ b/src/UniGetUI.Avalonia/Views/MainWindow.axaml.cs @@ -239,6 +239,7 @@ protected override void OnOpened(EventArgs e) SetupMicaAndAccentBorder(); UpdateWindowCornerPreference(); + UpdateCaptionButtonInset(); ActualThemeVariantChanged += (_, _) => { @@ -1198,6 +1199,28 @@ private void UpdateWindowCornerPreference() NativeMethods.DwmSetWindowAttribute(handle, DWMWA_WINDOW_CORNER_PREFERENCE, ref corner, sizeof(int)); } + private void UpdateCaptionButtonInset() + { + if (!OperatingSystem.IsWindows() || !WindowButtons.IsVisible) + return; + + if (TryGetPlatformHandle()?.Handle is not { } handle || handle == 0) + return; + + double inset = 0; + if (!NativeMethods.IsZoomed(handle)) + { + uint dpi = NativeMethods.GetDpiForWindow(handle); + if (dpi == 0) dpi = 96; + uint style = (uint)NativeMethods.GetWindowLongPtr(handle, GWL_STYLE).ToInt64(); + var frame = default(NativeMethods.RECT); + if (NativeMethods.AdjustWindowRectExForDpi(ref frame, style, false, 0, dpi)) + inset = frame.Right / (dpi / 96.0); + } + + WindowButtons.Margin = new Thickness(0, 0, inset, 0); + } + private void ApplyWindowBorderColor(nint handle) { int color; @@ -1241,7 +1264,11 @@ private static nint OnWindowsWndProc(nint hWnd, uint msg, nint wParam, nint lPar if ((msg == WM_SHOWWINDOW || (msg == WM_SIZE && (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED))) && Instance is { } cornerOwner) { - Dispatcher.UIThread.Post(cornerOwner.UpdateWindowCornerPreference); + Dispatcher.UIThread.Post(() => + { + cornerOwner.UpdateWindowCornerPreference(); + cornerOwner.UpdateCaptionButtonInset(); + }); } if (msg == WM_SETTINGCHANGE && Instance is { } trayOwner) @@ -1249,6 +1276,8 @@ private static nint OnWindowsWndProc(nint hWnd, uint msg, nint wParam, nint lPar trayOwner.UpdateSystemTrayStatus(); } + int borderEdge = msg == WM_NCHITTEST ? HitTestResizeBorder(hWnd, lParam) : HTNOWHERE; + // ── Snap Layouts: report HTMAXBUTTON over the custom maximize button so Win11 shows the // layout flyout, and emulate hover/press/click since input now arrives as NC messages. ── if (Instance is { } self && self.WindowButtons.IsVisible) @@ -1256,6 +1285,11 @@ private static nint OnWindowsWndProc(nint hWnd, uint msg, nint wParam, nint lPar switch (msg) { case WM_NCHITTEST: + if (borderEdge is not HTNOWHERE and not HTTOP) + { + handled = true; + return borderEdge; + } if (self.HitTestMaximizeButton(lParam)) { handled = true; @@ -1308,14 +1342,10 @@ private static nint OnWindowsWndProc(nint hWnd, uint msg, nint wParam, nint lPar } } - if (msg == WM_NCHITTEST) + if (borderEdge != HTNOWHERE) { - int edge = HitTestResizeBorder(hWnd, lParam); - if (edge != HTNOWHERE) - { - handled = true; - return edge; - } + handled = true; + return borderEdge; } // Force client = full window rect. Avalonia's ExtendClientArea handler only overrides