Skip to content

Commit ba3936e

Browse files
committed
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.
1 parent 92728a7 commit ba3936e

1 file changed

Lines changed: 47 additions & 0 deletions

File tree

src/Views/ChromelessWindow.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ public ChromelessWindow()
2626
{
2727
Focusable = true;
2828
Native.OS.SetupForWindow(this);
29+
PositionChanged += (_, _) => UpdateEdgeSnapInsets();
30+
Resized += (_, _) => UpdateEdgeSnapInsets();
2931
}
3032

3133
public void BeginMoveWindow(object _, PointerPressedEventArgs e)
@@ -89,6 +91,9 @@ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs chang
8991

9092
if (OperatingSystem.IsWindows() && change.Property == WindowStateProperty)
9193
Native.Win64Utilities.FixWindowFrame(this);
94+
95+
if (change.Property == WindowStateProperty)
96+
UpdateEdgeSnapInsets();
9297
}
9398

9499
protected override void OnKeyDown(KeyEventArgs e)
@@ -132,5 +137,47 @@ private void OnWindowBorderPointerPressed(object sender, PointerPressedEventArgs
132137
if (sender is Border { Tag: WindowEdge edge } && CanResize)
133138
BeginResizeDrag(edge, e);
134139
}
140+
141+
// The transparent padding around the window holds the self-drawn shadow
142+
// (keep the value in sync with "Window.custom_window_frame" style).
143+
// Collapse it on the side touching a screen edge so the content sits flush.
144+
private void UpdateEdgeSnapInsets()
145+
{
146+
if (!Classes.Contains("custom_window_frame"))
147+
return;
148+
149+
if (WindowState != WindowState.Normal)
150+
{
151+
// Let the "WindowState=Maximized" style take over
152+
ClearValue(PaddingProperty);
153+
return;
154+
}
155+
156+
var screen = Screens.ScreenFromWindow(this);
157+
if (screen == null)
158+
return;
159+
160+
var workArea = screen.WorkingArea;
161+
var right = Position.X + Bounds.Width;
162+
var bottom = Position.Y + Bounds.Height;
163+
164+
const double tolerance = 2.0;
165+
var snapTop = Position.Y <= workArea.Y + tolerance;
166+
var snapLeft = Position.X <= workArea.X + tolerance;
167+
var snapRight = right >= workArea.Right - tolerance;
168+
var snapBottom = bottom >= workArea.Bottom - tolerance;
169+
170+
if (!snapTop && !snapLeft && !snapRight && !snapBottom)
171+
{
172+
ClearValue(PaddingProperty);
173+
return;
174+
}
175+
176+
Padding = new Thickness(
177+
snapLeft ? 0 : 12,
178+
snapTop ? 0 : 12,
179+
snapRight ? 0 : 12,
180+
snapBottom ? 0 : 12);
181+
}
135182
}
136183
}

0 commit comments

Comments
 (0)