Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions src/Native/Linux.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,4 +171,58 @@ private string FindExecutable(string filename)
return File.Exists(local) ? local : string.Empty;
}
}

[SupportedOSPlatform("linux")]
public static class LinuxUtilities
{
public const string TiledFrameClass = "window_frame_tiled";

private const int EdgeTolerance = 2;

public static void UpdateCustomWindowFrameStyle(Window window)
{
if (OS.UseSystemWindowFrame || !window.Classes.Contains("custom_window_frame"))
return;

var tiled = IsWindowTiledOrSnapped(window);
if (tiled)
{
if (!window.Classes.Contains(TiledFrameClass))
window.Classes.Add(TiledFrameClass);
}
else if (window.Classes.Contains(TiledFrameClass))
{
window.Classes.Remove(TiledFrameClass);
}
}

private static bool IsWindowTiledOrSnapped(Window window)
{
if (window.WindowState is WindowState.Maximized or WindowState.FullScreen)
return false;

if (window.Screens is not { } screens)
return false;

var screen = screens.ScreenFromWindow(window);
if (screen == null)
return false;

var workArea = screen.WorkingArea;
var size = PixelSize.FromSize(new Size(window.Width, window.Height), window.DesktopScaling);
var frame = new PixelRect(window.Position, size);

var edgeCount = 0;
if (Math.Abs(frame.X - workArea.X) <= EdgeTolerance)
edgeCount++;
if (Math.Abs(frame.Right - workArea.Right) <= EdgeTolerance)
edgeCount++;
if (Math.Abs(frame.Y - workArea.Y) <= EdgeTolerance)
edgeCount++;
if (Math.Abs(frame.Bottom - workArea.Bottom) <= EdgeTolerance)
edgeCount++;

return edgeCount >= 2;
}
}
}
12 changes: 10 additions & 2 deletions src/Resources/Styles.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@
Cursor="BottomRightCorner"
Tag="{x:Static WindowEdge.SouthEast}"/>

<Grid Margin="{TemplateBinding Padding}" Effect="drop-shadow(0 0 12 #60000000)">
<Grid x:Name="PART_ContentHost" Margin="{TemplateBinding Padding}" Effect="drop-shadow(0 0 12 #60000000)">
<Border x:Name="PART_ContentRoot"
Background="{DynamicResource Brush.Window}"
BorderBrush="{DynamicResource Brush.WindowBorder}"
Expand Down Expand Up @@ -155,7 +155,15 @@
</Setter>
</Style>

<Style Selector="Window.custom_window_frame[WindowState=Maximized]">
<Style Selector="Window.custom_window_frame.window_frame_tiled /template/ Grid#PART_ContentHost">
<Setter Property="Effect" Value="{x:Null}"/>
</Style>

<Style Selector="Window.custom_window_frame.window_frame_tiled /template/ Border.resize_border">
<Setter Property="ZIndex" Value="1"/>
</Style>

<Style Selector="Window.custom_window_frame[WindowState=Maximized], Window.custom_window_frame.window_frame_tiled">
<Setter Property="Padding" Value="0"/>
<Setter Property="CornerRadius" Value="0"/>
</Style>
Expand Down
24 changes: 24 additions & 0 deletions src/Views/ChromelessWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ public ChromelessWindow()
{
Focusable = true;
Native.OS.SetupForWindow(this);

if (OperatingSystem.IsLinux() && !UseSystemWindowFrame)
{
PositionChanged += (_, _) => Native.LinuxUtilities.UpdateCustomWindowFrameStyle(this);
}
}

public void BeginMoveWindow(object _, PointerPressedEventArgs e)
Expand Down Expand Up @@ -81,6 +86,16 @@ protected override void OnLoaded(RoutedEventArgs e)

if (OperatingSystem.IsWindows())
Native.Win64Utilities.FixWindowFrame(this);
else if (OperatingSystem.IsLinux())
Native.LinuxUtilities.UpdateCustomWindowFrameStyle(this);
}

protected override void OnSizeChanged(SizeChangedEventArgs e)
{
base.OnSizeChanged(e);

if (OperatingSystem.IsLinux())
Native.LinuxUtilities.UpdateCustomWindowFrameStyle(this);
}

protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
Expand All @@ -89,6 +104,15 @@ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs chang

if (OperatingSystem.IsWindows() && change.Property == WindowStateProperty)
Native.Win64Utilities.FixWindowFrame(this);
else if (OperatingSystem.IsLinux() &&
Classes.Contains("custom_window_frame") &&
(change.Property == WindowStateProperty ||
change.Property == BoundsProperty ||
change.Property == WidthProperty ||
change.Property == HeightProperty))
{
Native.LinuxUtilities.UpdateCustomWindowFrameStyle(this);
}
}

protected override void OnKeyDown(KeyEventArgs e)
Expand Down