Skip to content

Commit 5a7eee7

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 5a7eee7

1 file changed

Lines changed: 46 additions & 0 deletions

File tree

src/Views/ChromelessWindow.cs

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

3132
public void BeginMoveWindow(object _, PointerPressedEventArgs e)
@@ -89,6 +90,9 @@ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs chang
8990

9091
if (OperatingSystem.IsWindows() && change.Property == WindowStateProperty)
9192
Native.Win64Utilities.FixWindowFrame(this);
93+
94+
if (change.Property == WindowStateProperty)
95+
UpdateEdgeSnapInsets();
9296
}
9397

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

0 commit comments

Comments
 (0)