From ba3936ebb7d151e3cd237b6ef4e5dc010acb62dd Mon Sep 17 00:00:00 2001 From: Gadfly Date: Wed, 16 Sep 2026 10:54:36 +0800 Subject: [PATCH] fix: collapse shadow padding when window touches a screen edge The custom window frame draws its shadow inside a 12px transparent padding that belongs to the window bounds, so window managers clamp the padded bounds against the screen edge and the visible content stops short of it. Collapse the padding on the touching side to let the content sit flush against the edge. --- src/Views/ChromelessWindow.cs | 47 +++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/Views/ChromelessWindow.cs b/src/Views/ChromelessWindow.cs index a06ab75656..0fc83764ba 100644 --- a/src/Views/ChromelessWindow.cs +++ b/src/Views/ChromelessWindow.cs @@ -26,6 +26,8 @@ public ChromelessWindow() { Focusable = true; Native.OS.SetupForWindow(this); + PositionChanged += (_, _) => UpdateEdgeSnapInsets(); + Resized += (_, _) => UpdateEdgeSnapInsets(); } public void BeginMoveWindow(object _, PointerPressedEventArgs e) @@ -89,6 +91,9 @@ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs chang if (OperatingSystem.IsWindows() && change.Property == WindowStateProperty) Native.Win64Utilities.FixWindowFrame(this); + + if (change.Property == WindowStateProperty) + UpdateEdgeSnapInsets(); } protected override void OnKeyDown(KeyEventArgs e) @@ -132,5 +137,47 @@ private void OnWindowBorderPointerPressed(object sender, PointerPressedEventArgs if (sender is Border { Tag: WindowEdge edge } && CanResize) BeginResizeDrag(edge, e); } + + // The transparent padding around the window holds the self-drawn shadow + // (keep the value in sync with "Window.custom_window_frame" style). + // Collapse it on the side touching a screen edge so the content sits flush. + private void UpdateEdgeSnapInsets() + { + if (!Classes.Contains("custom_window_frame")) + return; + + if (WindowState != WindowState.Normal) + { + // Let the "WindowState=Maximized" style take over + ClearValue(PaddingProperty); + return; + } + + var screen = Screens.ScreenFromWindow(this); + if (screen == null) + return; + + var workArea = screen.WorkingArea; + var right = Position.X + Bounds.Width; + var bottom = Position.Y + Bounds.Height; + + const double tolerance = 2.0; + var snapTop = Position.Y <= workArea.Y + tolerance; + var snapLeft = Position.X <= workArea.X + tolerance; + var snapRight = right >= workArea.Right - tolerance; + var snapBottom = bottom >= workArea.Bottom - tolerance; + + if (!snapTop && !snapLeft && !snapRight && !snapBottom) + { + ClearValue(PaddingProperty); + return; + } + + Padding = new Thickness( + snapLeft ? 0 : 12, + snapTop ? 0 : 12, + snapRight ? 0 : 12, + snapBottom ? 0 : 12); + } } }