style: border-less window style on Linux platform.

This commit is contained in:
leo 2024-03-14 18:23:36 +08:00
parent f4b396596b
commit 035300a612
23 changed files with 752 additions and 427 deletions

View file

@ -26,6 +26,8 @@ Opensouce Git GUI client.
* Revision Diffs
* GitFlow support
> **Linux** only tested on `Ubuntu 22.04` on `X11`.
## How to use
**To use this tool, you need to install Git first.**
@ -43,7 +45,6 @@ For **macOS** users:
For **Linux** users:
* `xdg-open` must be installed to support open native file manager.
* Only tested on `Ubuntu 22.04`.
## Screen Shots

View file

@ -50,7 +50,7 @@ namespace SourceGit {
manager.AddFontCollection(monospace);
});
Native.OS.SetupFonts(builder);
Native.OS.SetupApp(builder);
return builder;
}

View file

@ -2,13 +2,15 @@
using Avalonia.Data.Converters;
using Avalonia.Media;
using Avalonia;
using System.Runtime.InteropServices;
using System;
namespace SourceGit.Converters {
public static class WindowStateConverters {
public static FuncValueConverter<WindowState, Thickness> ToContentMargin =
new FuncValueConverter<WindowState, Thickness>(state => {
if (state == WindowState.Maximized && RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) {
if (OperatingSystem.IsWindows() && state == WindowState.Maximized) {
return new Thickness(6);
} else if (OperatingSystem.IsLinux() && state != WindowState.Maximized) {
return new Thickness(6);
} else {
return new Thickness(0);
@ -17,7 +19,7 @@ namespace SourceGit.Converters {
public static FuncValueConverter<WindowState, GridLength> ToTitleBarHeight =
new FuncValueConverter<WindowState, GridLength>(state => {
if (state == WindowState.Maximized && RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) {
if (state == WindowState.Maximized) {
return new GridLength(30);
} else {
return new GridLength(38);

View file

@ -6,7 +6,7 @@ using System.Runtime.Versioning;
namespace SourceGit.Native {
[SupportedOSPlatform("linux")]
internal class Linux : OS.IBackend {
public void SetupFonts(AppBuilder builder) {
public void SetupApp(AppBuilder builder) {
#if USE_FONT_INTER
builder.WithInterFont();
#endif

View file

@ -8,7 +8,7 @@ using System.Text;
namespace SourceGit.Native {
[SupportedOSPlatform("macOS")]
internal class MacOS : OS.IBackend {
public void SetupFonts(AppBuilder builder) {
public void SetupApp(AppBuilder builder) {
builder.With(new FontManagerOptions() {
DefaultFamilyName = "PingFang SC",
FontFallbacks = [

View file

@ -5,7 +5,7 @@ using System.Diagnostics;
namespace SourceGit.Native {
public static class OS {
public interface IBackend {
void SetupFonts(AppBuilder builder);
void SetupApp(AppBuilder builder);
string FindGitExecutable();
string FindVSCode();
@ -41,8 +41,8 @@ namespace SourceGit.Native {
}
}
public static void SetupFonts(AppBuilder builder) {
_backend?.SetupFonts(builder);
public static void SetupApp(AppBuilder builder) {
_backend?.SetupApp(builder);
}
public static string FindGitExecutable() {

View file

@ -13,7 +13,7 @@ namespace SourceGit.Native {
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode, SetLastError = false)]
private static extern bool PathFindOnPath([In, Out] StringBuilder pszFile, [In] string[] ppszOtherDirs);
public void SetupFonts(AppBuilder builder) {
public void SetupApp(AppBuilder builder) {
builder.With(new FontManagerOptions() {
DefaultFamilyName = "Microsoft YaHei UI",
FontFallbacks = [

View file

@ -9,24 +9,32 @@
x:DataType="v:About"
Icon="/App.ico"
Title="{DynamicResource Text.About}"
Background="{DynamicResource Brush.Window}"
Background="Transparent"
SizeToContent="WidthAndHeight"
CanResize="False"
WindowStartupLocation="CenterScreen"
ExtendClientAreaToDecorationsHint="{OnPlatform True, Linux=False}"
ExtendClientAreaChromeHints="{OnPlatform NoChrome, Linux=Default}">
ExtendClientAreaToDecorationsHint="True"
ExtendClientAreaChromeHints="NoChrome"
SystemDecorations="{OnPlatform Full, Linux=None}">
<Grid RowDefinitions="Auto,*">
<Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto" Height="30" IsVisible="{OnPlatform True, Linux=False}">
<!-- Custom window shadow for Linux -->
<Border Grid.Row="0" Grid.RowSpan="2"
Background="{DynamicResource Brush.Window}"
Effect="drop-shadow(0 0 6 #A0000000)"
IsVisible="{OnPlatform False, Linux=True}"/>
<!-- TitleBar -->
<Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto" Height="30">
<Border Grid.Column="0" Grid.ColumnSpan="3"
Background="{DynamicResource Brush.TitleBar}"
BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border0}"
IsHitTestVisible="False"/>
PointerPressed="BeginMoveWindow"/>
<Path Grid.Column="0"
Width="14" Height="14"
Margin="10,0,0,0"
Data="{StaticResource Icons.Info}"
IsVisible="{OnPlatform False, Windows=True}"/>
IsVisible="{OnPlatform True, macOS=False}"/>
<Grid Grid.Column="0" Classes="caption_button_box" Margin="2,4,0,0" IsVisible="{OnPlatform False, macOS=True}">
<Button Classes="caption_button_macos" Click="CloseWindow">
@ -46,12 +54,12 @@
<Button Grid.Column="2"
Classes="caption_button"
Click="CloseWindow"
IsVisible="{OnPlatform False, Windows=True}">
IsVisible="{OnPlatform True, macOS=False}">
<Path Data="{StaticResource Icons.Window.Close}"/>
</Button>
</Grid>
<Grid Grid.Row="1" ColumnDefinitions="Auto,*">
<Grid Grid.Row="1" ColumnDefinitions="Auto,*" Background="{DynamicResource Brush.Window}">
<Image Grid.Column="0"
Width="200" Height="200"
Margin="8,0"

View file

@ -17,6 +17,10 @@ namespace SourceGit.Views {
InitializeComponent();
}
private void BeginMoveWindow(object sender, PointerPressedEventArgs e) {
BeginMoveDrag(e);
}
private void CloseWindow(object sender, RoutedEventArgs e) {
Close();
}

View file

@ -10,25 +10,32 @@
x:DataType="vm:AssumeUnchangedManager"
Icon="/App.ico"
Title="{DynamicResource Text.AssumeUnchanged}"
Background="{DynamicResource Brush.Window}"
Background="Transparent"
Width="600" Height="400"
CanResize="False"
WindowStartupLocation="CenterOwner"
ExtendClientAreaToDecorationsHint="{OnPlatform True, Linux=False}"
ExtendClientAreaChromeHints="{OnPlatform NoChrome, Linux=Default}">
ExtendClientAreaToDecorationsHint="True"
ExtendClientAreaChromeHints="NoChrome"
SystemDecorations="{OnPlatform Full, Linux=None}">
<Grid RowDefinitions="Auto,*">
<!-- Custom window shadow for Linux -->
<Border Grid.Row="0" Grid.RowSpan="2"
Background="{DynamicResource Brush.Window}"
Effect="drop-shadow(0 0 6 #A0000000)"
IsVisible="{OnPlatform False, Linux=True}"/>
<!-- TitleBar -->
<Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto" Height="30" IsVisible="{OnPlatform True, Linux=False}">
<Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto" Height="30">
<Border Grid.Column="0" Grid.ColumnSpan="3"
Background="{DynamicResource Brush.TitleBar}"
BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border0}"
IsHitTestVisible="False"/>
PointerPressed="BeginMoveWindow"/>
<Path Grid.Column="0"
Width="14" Height="14"
Margin="10,0,0,0"
Data="{StaticResource Icons.File.Ignore}"
IsVisible="{OnPlatform False, Windows=True}"/>
IsVisible="{OnPlatform True, macOS=False}"/>
<Grid Grid.Column="0" Classes="caption_button_box" Margin="2,4,0,0" IsVisible="{OnPlatform False, macOS=True}">
<Button Classes="caption_button_macos" Click="CloseWindow">
@ -48,14 +55,14 @@
<Button Grid.Column="2"
Classes="caption_button"
Click="CloseWindow"
IsVisible="{OnPlatform False, Windows=True}">
IsVisible="{OnPlatform True, macOS=False}">
<Path Data="{StaticResource Icons.Window.Close}"/>
</Button>
</Grid>
<!-- Unchanged Files -->
<DataGrid Grid.Row="1"
Margin="8"
<Grid Grid.Row="1" Background="{DynamicResource Brush.Window}">
<DataGrid Margin="8"
Background="{DynamicResource Brush.Contents}"
ItemsSource="{Binding Files}"
SelectionMode="Single"
@ -97,12 +104,12 @@
</DataGrid>
<!-- Empty -->
<StackPanel Grid.Row="2"
Orientation="Vertical"
<StackPanel Orientation="Vertical"
HorizontalAlignment="Center" VerticalAlignment="Center"
IsVisible="{Binding Files.Count, Converter={x:Static c:IntConverters.IsZero}}">
<Path Width="48" Height="48" Data="{StaticResource Icons.Empty}" Fill="{DynamicResource Brush.FG2}"/>
<TextBlock Margin="0,16,0,0" Text="{DynamicResource Text.AssumeUnchanged.Empty}" Foreground="{DynamicResource Brush.FG2}"/>
</StackPanel>
</Grid>
</Grid>
</Window>

View file

@ -1,4 +1,5 @@
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
namespace SourceGit.Views {
@ -7,6 +8,10 @@ namespace SourceGit.Views {
InitializeComponent();
}
private void BeginMoveWindow(object sender, PointerPressedEventArgs e) {
BeginMoveDrag(e);
}
private void CloseWindow(object sender, RoutedEventArgs e) {
Close();
}

View file

@ -12,25 +12,32 @@
x:DataType="vm:Blame"
Icon="/App.ico"
Title="{DynamicResource Text.Blame}"
Background="Transparent"
WindowStartupLocation="CenterOwner"
BorderThickness="1"
BorderBrush="{DynamicResource Brush.Border0}"
Background="{DynamicResource Brush.Window}"
MinWidth="1280" MinHeight="720"
ExtendClientAreaToDecorationsHint="{OnPlatform True, Linux=False}"
ExtendClientAreaChromeHints="{OnPlatform NoChrome, Linux=Default}">
ExtendClientAreaToDecorationsHint="True"
ExtendClientAreaChromeHints="NoChrome"
SystemDecorations="{OnPlatform Full, Linux=None}">
<Grid Margin="{Binding #me.WindowState, Converter={x:Static c:WindowStateConverters.ToContentMargin}}">
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Custom window shadow for Linux -->
<Border Grid.Row="0" Grid.RowSpan="2"
Background="{DynamicResource Brush.Window}"
Effect="drop-shadow(0 0 6 #A0000000)"
IsVisible="{OnPlatform False, Linux=True}"/>
<!-- TitleBar -->
<Grid Grid.Row="0" ColumnDefinitions="Auto,Auto,Auto,*,Auto">
<!-- Bottom border -->
<Border Grid.Column="0" Grid.ColumnSpan="5"
Background="{DynamicResource Brush.TitleBar}"
BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border2}"
IsHitTestVisible="False"/>
DoubleTapped="MaximizeOrRestoreWindow"
PointerPressed="BeginMoveWindow"/>
<!-- Caption Buttons (macOS) -->
<Border Grid.Column="0" IsVisible="{OnPlatform False, macOS=True}">
@ -40,19 +47,20 @@
<!-- Icon -->
<Path Grid.Column="1" Margin="8,0,0,0" Width="12" Height="12" Data="{StaticResource Icons.Blame}"/>
<!-- Title (Hide on Linux) -->
<TextBlock Grid.Column="2" Margin="8,0,0,0" Text="{DynamicResource Text.Blame}" FontWeight="Bold" IsHitTestVisible="False" VerticalAlignment="Center" IsVisible="{OnPlatform True, Linux=False}"/>
<!-- Title -->
<TextBlock Grid.Column="2" Margin="8,0,0,0" Text="{DynamicResource Text.Blame}" FontWeight="Bold" IsHitTestVisible="False" VerticalAlignment="Center"/>
<!-- Blame information -->
<TextBlock Grid.Column="3" Margin="8,0,0,0" Text="{Binding Title}" FontSize="11" FontStyle="Italic" IsHitTestVisible="False" VerticalAlignment="Center"/>
<!-- Caption Buttons (Windows) -->
<Border Grid.Column="4" IsVisible="{OnPlatform False, Windows=True}">
<!-- Caption Buttons (Windows/Linux) -->
<Border Grid.Column="4" IsVisible="{OnPlatform True, macOS=False}">
<v:CaptionButtons/>
</Border>
</Grid>
<Grid Grid.Row="1">
<!-- Body -->
<Grid Grid.Row="1" Background="{DynamicResource Brush.Window}">
<!-- Blame View -->
<v:BlameTextEditor HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto"
@ -78,5 +86,64 @@
Data="{StaticResource Icons.Loading}"
IsVisible="{Binding Data, Converter={x:Static ObjectConverters.IsNull}}"/>
</Grid>
<!-- Custom window sizer for Linux -->
<Grid Grid.Row="0" Grid.RowSpan="2" IsVisible="{OnPlatform False, Linux=True}">
<Border Width="4" Height="4"
Background="Transparent"
HorizontalAlignment="Left" VerticalAlignment="Top"
Cursor="TopLeftCorner"
Tag="{x:Static WindowEdge.NorthWest}"
PointerPressed="CustomResizeWindow"/>
<Border Height="4" Margin="4,0"
Background="Transparent"
HorizontalAlignment="Stretch" VerticalAlignment="Top"
Cursor="TopSide"
Tag="{x:Static WindowEdge.North}"
PointerPressed="CustomResizeWindow"/>
<Border Width="4" Height="4"
Background="Transparent"
HorizontalAlignment="Right" VerticalAlignment="Top"
Cursor="TopRightCorner"
Tag="{x:Static WindowEdge.NorthEast}"
PointerPressed="CustomResizeWindow"/>
<Border Width="4" Margin="0,4"
Background="Transparent"
HorizontalAlignment="Left" VerticalAlignment="Stretch"
Cursor="LeftSide"
Tag="{x:Static WindowEdge.West}"
PointerPressed="CustomResizeWindow"/>
<Border Width="4" Margin="0,4"
Background="Transparent"
HorizontalAlignment="Right" VerticalAlignment="Stretch"
Cursor="RightSide"
Tag="{x:Static WindowEdge.East}"
PointerPressed="CustomResizeWindow"/>
<Border Width="4" Height="4"
Background="Transparent"
HorizontalAlignment="Left" VerticalAlignment="Bottom"
Cursor="BottomLeftCorner"
Tag="{x:Static WindowEdge.SouthWest}"
PointerPressed="CustomResizeWindow"/>
<Border Height="4" Margin="4,0"
Background="Transparent"
HorizontalAlignment="Stretch" VerticalAlignment="Bottom"
Cursor="BottomSide"
Tag="{x:Static WindowEdge.South}"
PointerPressed="CustomResizeWindow"/>
<Border Width="4" Height="4"
Background="Transparent"
HorizontalAlignment="Right" VerticalAlignment="Bottom"
Cursor="BottomRightCorner"
Tag="{x:Static WindowEdge.SouthEast}"
PointerPressed="CustomResizeWindow"/>
</Grid>
</Grid>
</Window>

View file

@ -308,6 +308,27 @@ namespace SourceGit.Views {
InitializeComponent();
}
private void MaximizeOrRestoreWindow(object sender, TappedEventArgs e) {
if (WindowState == WindowState.Maximized) {
WindowState = WindowState.Normal;
} else {
WindowState = WindowState.Maximized;
}
e.Handled = true;
}
private void CustomResizeWindow(object sender, PointerPressedEventArgs e) {
if (sender is Border border) {
if (border.Tag is WindowEdge edge) {
BeginResizeDrag(edge, e);
}
}
}
private void BeginMoveWindow(object sender, PointerPressedEventArgs e) {
BeginMoveDrag(e);
}
protected override void OnClosed(EventArgs e) {
base.OnClosed(e);
GC.Collect();

View file

@ -12,24 +12,31 @@
x:Name="me"
Icon="/App.ico"
Title="{DynamicResource Text.FileHistory}"
Background="Transparent"
MinWidth="1280" MinHeight="720"
BorderThickness="1"
BorderBrush="{DynamicResource Brush.Border0}"
Background="{DynamicResource Brush.Window}"
ExtendClientAreaToDecorationsHint="{OnPlatform True, Linux=False}"
ExtendClientAreaChromeHints="{OnPlatform NoChrome, Linux=Default}">
ExtendClientAreaToDecorationsHint="True"
ExtendClientAreaChromeHints="NoChrome"
SystemDecorations="{OnPlatform Full, Linux=None}">
<Grid Margin="{Binding #me.WindowState, Converter={x:Static c:WindowStateConverters.ToContentMargin}}">
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Custom window shadow for Linux -->
<Border Grid.Row="0" Grid.RowSpan="2"
Background="{DynamicResource Brush.Window}"
Effect="drop-shadow(0 0 6 #A0000000)"
IsVisible="{OnPlatform False, Linux=True}"/>
<!-- TitleBar -->
<Grid Grid.Row="0" ColumnDefinitions="Auto,Auto,Auto,*,Auto">
<!-- Bottom border -->
<Border Grid.Column="0" Grid.ColumnSpan="5"
Background="{DynamicResource Brush.TitleBar}"
BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border0}"
IsHitTestVisible="False"/>
DoubleTapped="MaximizeOrRestoreWindow"
PointerPressed="BeginMoveWindow"/>
<!-- Caption Buttons (macOS) -->
<Border Grid.Column="0" IsVisible="{OnPlatform False, macOS=True}">
@ -39,19 +46,20 @@
<!-- Icon -->
<Path Grid.Column="1" Margin="8,0,0,0" Width="12" Height="12" Stretch="Uniform" Data="{StaticResource Icons.Histories}"/>
<!-- Title (Hide on Linux) -->
<TextBlock Grid.Column="2" Margin="4,0,0,0" Text="{DynamicResource Text.FileHistory}" FontWeight="Bold" IsHitTestVisible="False" VerticalAlignment="Center" IsVisible="{OnPlatform True, Linux=False}"/>
<!-- Title -->
<TextBlock Grid.Column="2" Margin="4,0,0,0" Text="{DynamicResource Text.FileHistory}" FontWeight="Bold" IsHitTestVisible="False" VerticalAlignment="Center"/>
<!-- Target File -->
<TextBlock Grid.Column="3" Margin="8,0,0,0" Text="{Binding File}" FontSize="11" FontStyle="Italic" IsHitTestVisible="False" VerticalAlignment="Center"/>
<!-- Caption Buttons (Windows) -->
<Border Grid.Column="4" IsVisible="{OnPlatform False, Windows=true}">
<!-- Caption Buttons (Windows/Linux) -->
<Border Grid.Column="4" IsVisible="{OnPlatform True, macOS=False}">
<v:CaptionButtons/>
</Border>
</Grid>
<Grid Grid.Row="1">
<!-- Body -->
<Grid Grid.Row="1" Background="{DynamicResource Brush.Window}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300" MinWidth="300" MaxWidth="600"/>
<ColumnDefinition Width="1"/>
@ -109,5 +117,64 @@
</ContentControl>
</Grid>
</Grid>
<!-- Custom window sizer for Linux -->
<Grid Grid.Row="0" Grid.RowSpan="2" IsVisible="{OnPlatform False, Linux=True}">
<Border Width="4" Height="4"
Background="Transparent"
HorizontalAlignment="Left" VerticalAlignment="Top"
Cursor="TopLeftCorner"
Tag="{x:Static WindowEdge.NorthWest}"
PointerPressed="CustomResizeWindow"/>
<Border Height="4" Margin="4,0"
Background="Transparent"
HorizontalAlignment="Stretch" VerticalAlignment="Top"
Cursor="TopSide"
Tag="{x:Static WindowEdge.North}"
PointerPressed="CustomResizeWindow"/>
<Border Width="4" Height="4"
Background="Transparent"
HorizontalAlignment="Right" VerticalAlignment="Top"
Cursor="TopRightCorner"
Tag="{x:Static WindowEdge.NorthEast}"
PointerPressed="CustomResizeWindow"/>
<Border Width="4" Margin="0,4"
Background="Transparent"
HorizontalAlignment="Left" VerticalAlignment="Stretch"
Cursor="LeftSide"
Tag="{x:Static WindowEdge.West}"
PointerPressed="CustomResizeWindow"/>
<Border Width="4" Margin="0,4"
Background="Transparent"
HorizontalAlignment="Right" VerticalAlignment="Stretch"
Cursor="RightSide"
Tag="{x:Static WindowEdge.East}"
PointerPressed="CustomResizeWindow"/>
<Border Width="4" Height="4"
Background="Transparent"
HorizontalAlignment="Left" VerticalAlignment="Bottom"
Cursor="BottomLeftCorner"
Tag="{x:Static WindowEdge.SouthWest}"
PointerPressed="CustomResizeWindow"/>
<Border Height="4" Margin="4,0"
Background="Transparent"
HorizontalAlignment="Stretch" VerticalAlignment="Bottom"
Cursor="BottomSide"
Tag="{x:Static WindowEdge.South}"
PointerPressed="CustomResizeWindow"/>
<Border Width="4" Height="4"
Background="Transparent"
HorizontalAlignment="Right" VerticalAlignment="Bottom"
Cursor="BottomRightCorner"
Tag="{x:Static WindowEdge.SouthEast}"
PointerPressed="CustomResizeWindow"/>
</Grid>
</Grid>
</Window>

View file

@ -7,6 +7,27 @@ namespace SourceGit.Views {
InitializeComponent();
}
private void MaximizeOrRestoreWindow(object sender, TappedEventArgs e) {
if (WindowState == WindowState.Maximized) {
WindowState = WindowState.Normal;
} else {
WindowState = WindowState.Maximized;
}
e.Handled = true;
}
private void CustomResizeWindow(object sender, PointerPressedEventArgs e) {
if (sender is Border border) {
if (border.Tag is WindowEdge edge) {
BeginResizeDrag(edge, e);
}
}
}
private void BeginMoveWindow(object sender, PointerPressedEventArgs e) {
BeginMoveDrag(e);
}
private void OnPressedSHA(object sender, PointerPressedEventArgs e) {
if (sender is TextBlock block) {
var histories = DataContext as ViewModels.FileHistories;

View file

@ -7,24 +7,32 @@
x:Class="SourceGit.Views.Hotkeys"
Icon="/App.ico"
Title="{DynamicResource Text.Hotkeys}"
Background="{DynamicResource Brush.Window}"
Background="Transparent"
SizeToContent="WidthAndHeight"
CanResize="False"
WindowStartupLocation="CenterOwner"
ExtendClientAreaToDecorationsHint="{OnPlatform True, Linux=False}"
ExtendClientAreaChromeHints="{OnPlatform NoChrome, Linux=Default}">
ExtendClientAreaToDecorationsHint="True"
ExtendClientAreaChromeHints="NoChrome"
SystemDecorations="{OnPlatform Full, Linux=None}">
<Grid RowDefinitions="Auto,*">
<Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto" Height="30" IsVisible="{OnPlatform True, Linux=False}">
<!-- Custom window shadow for Linux -->
<Border Grid.Row="0" Grid.RowSpan="2"
Background="{DynamicResource Brush.Window}"
Effect="drop-shadow(0 0 6 #A0000000)"
IsVisible="{OnPlatform False, Linux=True}"/>
<!-- TitleBar -->
<Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto" Height="30">
<Border Grid.Column="0" Grid.ColumnSpan="3"
Background="{DynamicResource Brush.TitleBar}"
BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border0}"
IsHitTestVisible="False"/>
PointerPressed="BeginMoveWindow"/>
<Path Grid.Column="0"
Width="14" Height="14"
Margin="10,0,0,0"
Data="{StaticResource Icons.Hotkeys}"
IsVisible="{OnPlatform False, Windows=True}"/>
IsVisible="{OnPlatform True, macOS=False}"/>
<Grid Grid.Column="0" Classes="caption_button_box" Margin="2,4,0,0" IsVisible="{OnPlatform False, macOS=True}">
<Button Classes="caption_button_macos" Click="CloseWindow">
@ -44,12 +52,14 @@
<Button Grid.Column="2"
Classes="caption_button"
Click="CloseWindow"
IsVisible="{OnPlatform False, Windows=True}">
IsVisible="{OnPlatform True, macOS=False}">
<Path Data="{StaticResource Icons.Window.Close}"/>
</Button>
</Grid>
<StackPanel Grid.Row="1" Orientation="Vertical" Margin="16,8,16,16">
<!-- Body -->
<Border Grid.Row="1" Background="{DynamicResource Brush.Window}">
<StackPanel Orientation="Vertical" Margin="16,8,16,16">
<TextBlock Text="{DynamicResource Text.Hotkeys.Global}"
Foreground="{DynamicResource Brush.FG2}"
FontWeight="Bold"
@ -113,5 +123,6 @@
<TextBlock Grid.Row="3" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.TextEditor.CloseSearch}" />
</Grid>
</StackPanel>
</Border>
</Grid>
</Window>

View file

@ -1,4 +1,5 @@
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
namespace SourceGit.Views {
@ -7,6 +8,10 @@ namespace SourceGit.Views {
InitializeComponent();
}
private void BeginMoveWindow(object sender, PointerPressedEventArgs e) {
BeginMoveDrag(e);
}
private void CloseWindow(object sender, RoutedEventArgs e) {
Close();
}

View file

@ -12,13 +12,12 @@
x:Name="me"
Icon="/App.ico"
Title="SourceGit"
BorderThickness="1"
BorderBrush="{DynamicResource Brush.Border0}"
Background="{DynamicResource Brush.Window}"
Background="Transparent"
MinWidth="1280" MinHeight="720"
WindowStartupLocation="CenterScreen"
ExtendClientAreaToDecorationsHint="{OnPlatform True, Linux=False}"
ExtendClientAreaChromeHints="{OnPlatform NoChrome, Linux=Default}">
ExtendClientAreaToDecorationsHint="True"
ExtendClientAreaChromeHints="NoChrome"
SystemDecorations="{OnPlatform Full, Linux=None}">
<Window.Resources>
<SolidColorBrush x:Key="SystemControlErrorTextForegroundBrush" Color="Red"/>
</Window.Resources>
@ -29,12 +28,20 @@
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Custom window shadow for Linux -->
<Border Grid.Row="0" Grid.RowSpan="2"
Background="{DynamicResource Brush.Window}"
Effect="drop-shadow(0 0 6 #A0000000)"
IsVisible="{OnPlatform False, Linux=True}"/>
<!-- Custom TitleBar -->
<Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto">
<!-- Bottom border -->
<Border Grid.Column="0" Grid.ColumnSpan="3"
Background="{DynamicResource Brush.TitleBar}"
BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border0}"
IsHitTestVisible="False"/>
DoubleTapped="MaximizeOrRestoreWindow"
PointerPressed="BeginMoveWindow"/>
<!-- Caption Buttons (macOS) -->
<Border Grid.Column="0" VerticalAlignment="Stretch" Margin="2,0,8,3" IsVisible="{OnPlatform False, macOS=True}">
@ -233,8 +240,8 @@
</Button>
</StackPanel>
<!-- Caption Buttons (Windows)-->
<Border Grid.Column="2" Margin="32,0,0,0" IsVisible="{OnPlatform False, Windows=True}">
<!-- Caption Buttons (Windows/Linux)-->
<Border Grid.Column="2" Margin="32,0,0,0" IsVisible="{OnPlatform True, macOS=False}">
<v:CaptionButtons Height="30" VerticalAlignment="Top"/>
</Border>
</Grid>
@ -364,5 +371,64 @@
</ItemsControl>
</ScrollViewer>
</Grid>
<!-- Custom window sizer for Linux -->
<Grid Grid.Row="0" Grid.RowSpan="2" IsVisible="{OnPlatform False, Linux=True}">
<Border Width="4" Height="4"
Background="Transparent"
HorizontalAlignment="Left" VerticalAlignment="Top"
Cursor="TopLeftCorner"
Tag="{x:Static WindowEdge.NorthWest}"
PointerPressed="CustomResizeWindow"/>
<Border Height="4" Margin="4,0"
Background="Transparent"
HorizontalAlignment="Stretch" VerticalAlignment="Top"
Cursor="TopSide"
Tag="{x:Static WindowEdge.North}"
PointerPressed="CustomResizeWindow"/>
<Border Width="4" Height="4"
Background="Transparent"
HorizontalAlignment="Right" VerticalAlignment="Top"
Cursor="TopRightCorner"
Tag="{x:Static WindowEdge.NorthEast}"
PointerPressed="CustomResizeWindow"/>
<Border Width="4" Margin="0,4"
Background="Transparent"
HorizontalAlignment="Left" VerticalAlignment="Stretch"
Cursor="LeftSide"
Tag="{x:Static WindowEdge.West}"
PointerPressed="CustomResizeWindow"/>
<Border Width="4" Margin="0,4"
Background="Transparent"
HorizontalAlignment="Right" VerticalAlignment="Stretch"
Cursor="RightSide"
Tag="{x:Static WindowEdge.East}"
PointerPressed="CustomResizeWindow"/>
<Border Width="4" Height="4"
Background="Transparent"
HorizontalAlignment="Left" VerticalAlignment="Bottom"
Cursor="BottomLeftCorner"
Tag="{x:Static WindowEdge.SouthWest}"
PointerPressed="CustomResizeWindow"/>
<Border Height="4" Margin="4,0"
Background="Transparent"
HorizontalAlignment="Stretch" VerticalAlignment="Bottom"
Cursor="BottomSide"
Tag="{x:Static WindowEdge.South}"
PointerPressed="CustomResizeWindow"/>
<Border Width="4" Height="4"
Background="Transparent"
HorizontalAlignment="Right" VerticalAlignment="Bottom"
Cursor="BottomRightCorner"
Tag="{x:Static WindowEdge.SouthEast}"
PointerPressed="CustomResizeWindow"/>
</Grid>
</Grid>
</Window>

View file

@ -126,6 +126,14 @@ namespace SourceGit.Views {
e.Handled = true;
}
private void CustomResizeWindow(object sender, PointerPressedEventArgs e) {
if (sender is Border border) {
if (border.Tag is WindowEdge edge) {
BeginResizeDrag(edge, e);
}
}
}
private void BeginMoveWindow(object sender, PointerPressedEventArgs e) {
BeginMoveDrag(e);
}

View file

@ -13,24 +13,32 @@
x:Name="me"
Icon="/App.ico"
Title="{DynamicResource Text.Preference}"
Background="{DynamicResource Brush.Window}"
Background="Transparent"
Width="600" SizeToContent="Height"
CanResize="False"
WindowStartupLocation="CenterScreen"
ExtendClientAreaToDecorationsHint="{OnPlatform True, Linux=False}"
ExtendClientAreaChromeHints="{OnPlatform NoChrome, Linux=Default}">
ExtendClientAreaToDecorationsHint="True"
ExtendClientAreaChromeHints="NoChrome"
SystemDecorations="{OnPlatform Full, Linux=None}">
<Grid RowDefinitions="Auto,Auto">
<Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto" Height="30" IsVisible="{OnPlatform True, Linux=False}">
<!-- Custom window shadow for Linux -->
<Border Grid.Row="0" Grid.RowSpan="2"
Background="{DynamicResource Brush.Window}"
Effect="drop-shadow(0 0 6 #A0000000)"
IsVisible="{OnPlatform False, Linux=True}"/>
<!-- TitleBar -->
<Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto" Height="30">
<Border Grid.Column="0" Grid.ColumnSpan="3"
Background="{DynamicResource Brush.TitleBar}"
BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border0}"
IsHitTestVisible="False"/>
PointerPressed="BeginMoveWindow"/>
<Path Grid.Column="0"
Width="14" Height="14"
Data="{StaticResource Icons.Settings2}"
Margin="10,0,0,0"
IsVisible="{OnPlatform False, Windows=True}"/>
IsVisible="{OnPlatform True, macOS=False}"/>
<Grid Grid.Column="0" Classes="caption_button_box" Margin="2,4,0,0" IsVisible="{OnPlatform False, macOS=True}">
<Button Classes="caption_button_macos" Click="CloseWindow">
@ -47,12 +55,14 @@
HorizontalAlignment="Center" VerticalAlignment="Center"
IsHitTestVisible="False"/>
<Button Grid.Column="2" Classes="caption_button" Click="CloseWindow" IsVisible="{OnPlatform False, Windows=True}">
<Button Grid.Column="2" Classes="caption_button" Click="CloseWindow" IsVisible="{OnPlatform True, macOS=False}">
<Path Data="{StaticResource Icons.Window.Close}"/>
</Button>
</Grid>
<TabControl Grid.Row="1">
<!-- Body -->
<Border Grid.Row="1" Background="{DynamicResource Brush.Window}">
<TabControl>
<TabItem>
<TabItem.Header>
<TextBlock Classes="tab_header" Text="{DynamicResource Text.Preference.General}"/>
@ -328,5 +338,6 @@
</Grid>
</TabItem>
</TabControl>
</Border>
</Grid>
</Window>

View file

@ -1,4 +1,5 @@
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Platform.Storage;
using System;
@ -58,6 +59,10 @@ namespace SourceGit.Views {
txtVersion.Text = ver;
}
private void BeginMoveWindow(object sender, PointerPressedEventArgs e) {
BeginMoveDrag(e);
}
private void CloseWindow(object sender, RoutedEventArgs e) {
var cmd = new Commands.Config(null);

View file

@ -9,15 +9,27 @@
x:Class="SourceGit.Views.Statistics"
x:DataType="vm:Statistics"
Title="{DynamicResource Text.Statistics}"
Background="{DynamicResource Brush.Window}"
Background="Transparent"
Width="800" Height="450"
WindowStartupLocation="CenterOwner"
CanResize="False"
ExtendClientAreaToDecorationsHint="{OnPlatform True, Linux=False}"
ExtendClientAreaChromeHints="{OnPlatform NoChrome, Linux=Default}">
ExtendClientAreaToDecorationsHint="True"
ExtendClientAreaChromeHints="NoChrome"
SystemDecorations="{OnPlatform Full, Linux=None}">
<Grid RowDefinitions="Auto,Auto,*">
<!-- Custom window shadow for Linux -->
<Border Grid.Row="0" Grid.RowSpan="3"
Background="{DynamicResource Brush.Window}"
Effect="drop-shadow(0 0 6 #A0000000)"
IsVisible="{OnPlatform False, Linux=True}"/>
<!-- Window BG -->
<Border Grid.Row="1" Grid.RowSpan="2"
Background="{DynamicResource Brush.Window}"
IsVisible="{OnPlatform True, Linux=False}"/>
<!-- Title bar -->
<Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto" Height="30" IsVisible="{OnPlatform True, Linux=False}">
<Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto" Height="30">
<Border Grid.Column="0" Grid.ColumnSpan="3"
Background="{DynamicResource Brush.TitleBar}"
BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border0}"
@ -27,7 +39,7 @@
Width="14" Height="14"
Margin="10,0,0,0"
Data="{StaticResource Icons.Statistics}"
IsVisible="{OnPlatform False, Windows=True}"/>
IsVisible="{OnPlatform True, macOS=False}"/>
<Grid Grid.Column="0" Classes="caption_button_box" Margin="2,4,0,0" IsVisible="{OnPlatform False, macOS=True}">
<Button Classes="caption_button_macos" Click="CloseWindow">
@ -47,7 +59,7 @@
<Button Grid.Column="2"
Classes="caption_button"
Click="CloseWindow"
IsVisible="{OnPlatform False, Windows=True}">
IsVisible="{OnPlatform True, macOS=False}">
<Path Data="{StaticResource Icons.Window.Close}"/>
</Button>
</Grid>

View file

@ -191,6 +191,10 @@ namespace SourceGit.Views {
InitializeComponent();
}
private void BeginMoveWindow(object sender, PointerPressedEventArgs e) {
BeginMoveDrag(e);
}
private void CloseWindow(object sender, RoutedEventArgs e) {
Close();
}