Skip to content

Commit

Permalink
Fix window border issues (fixes #1)
Browse files Browse the repository at this point in the history
  • Loading branch information
ArchLeaders committed Oct 13, 2023
1 parent 9b54729 commit d7fc00a
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 97 deletions.
22 changes: 22 additions & 0 deletions src/NxEditor.Core/Extensions/Win32Extension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Avalonia.Platform;
using System.Runtime.InteropServices;

namespace NxEditor.Core.Extensions;

public partial class Win32Extension
{
[Flags]
private enum SetWindowPosFlags : uint
{
HideWindow = 128,
ShowWindow = 64
}

[LibraryImport("user32.dll", SetLastError = true)]
private static partial int SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags);

public static void FixAfterMaximizing(IntPtr hWnd, Screen screen)
{
SetWindowPos(hWnd, IntPtr.Zero, screen.WorkingArea.X, screen.WorkingArea.Y, screen.WorkingArea.Width, screen.WorkingArea.Height, (uint)SetWindowPosFlags.ShowWindow);
}
}
15 changes: 7 additions & 8 deletions src/NxEditor/NxEditor.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<OutputType>Exe</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net7.0</TargetFramework>
<TrimeMode>link</TrimeMode>
</PropertyGroup>
Expand All @@ -22,14 +21,14 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Avalonia" Version="11.0.0" />
<PackageReference Include="Avalonia" Version="11.1.999-cibuild0040597-beta" />
<PackageReference Include="Avalonia.AvaloniaEdit" Version="11.0.1" />
<PackageReference Include="Avalonia.Desktop" Version="11.0.0" />
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.0.0" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.0.0" />
<PackageReference Include="AvaloniaEdit.TextMate" Version="11.0.0" />
<PackageReference Include="Dock.Avalonia" Version="11.0.0" />
<PackageReference Include="Dock.Serializer" Version="11.0.0" />
<PackageReference Include="Avalonia.Desktop" Version="11.1.999-cibuild0040597-beta" />
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.1.999-cibuild0040597-beta" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.1.999-cibuild0040597-beta" />
<PackageReference Include="AvaloniaEdit.TextMate" Version="11.0.1" />
<PackageReference Include="Dock.Avalonia" Version="11.0.0.2" />
<PackageReference Include="Dock.Serializer" Version="11.0.0.2" />
<PackageReference Include="Projektanker.Icons.Avalonia" Version="6.6.0" />
<PackageReference Include="Projektanker.Icons.Avalonia.FontAwesome" Version="6.6.0" />

Expand Down
6 changes: 3 additions & 3 deletions src/NxEditor/Views/ShellView.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@
d:DesignWidth="800"
x:DataType="local:ShellViewModel"
Background="{DynamicResource SystemChromeLowColor}"
ExtendClientAreaChromeHints="NoChrome"
ExtendClientAreaToDecorationsHint="True"
Icon="/Assets/icon.ico"
SystemDecorations="BorderOnly"
mc:Ignorable="d">
<Grid Name="PointerClient"
Background="Transparent"
RowDefinitions="30,*,20">
<Grid Name="PointerClient" RowDefinitions="30,*,20">

<Border Name="ChromeClient"
Background="{DynamicResource SystemChromeHighColor}"
Expand Down
113 changes: 27 additions & 86 deletions src/NxEditor/Views/ShellView.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Media;
using Avalonia.Platform;
using Avalonia.Platform.Storage;
using NxEditor.Core.Extensions;
using NxEditor.PluginBase.Models;

namespace NxEditor.Views;
Expand All @@ -19,101 +21,24 @@ public ShellView()
};

ChromeClient.PointerPressed += (s, e) => {
if (!IsInResizeBorder(e, out _)) {
BeginMoveDrag(e);
}
};

ResizeClient.PointerPressed += (s, e) => {
if (IsInResizeBorder(e, out WindowEdge edge)) {
BeginResizeDrag(edge, e);
}
};

PointerClient.PointerMoved += (s, e) => {
if (IsInResizeBorder(e, out WindowEdge edge) && e.Source is Border border && border.Name is "ResizeClient" or "ChromeClient" or "ChromeStack") {
ChromeStack.IsHitTestVisible = false;
Cursor = new(edge switch {
WindowEdge.NorthWest => StandardCursorType.TopLeftCorner,
WindowEdge.NorthEast => StandardCursorType.TopRightCorner,
WindowEdge.SouthWest => StandardCursorType.BottomLeftCorner,
WindowEdge.SouthEast => StandardCursorType.BottomRightCorner,
WindowEdge.North or WindowEdge.South => StandardCursorType.SizeNorthSouth,
WindowEdge.West or WindowEdge.East => StandardCursorType.SizeWestEast,
_ => StandardCursorType.Arrow,
});
}
else {
ChromeStack.IsHitTestVisible = true;
Cursor = new(StandardCursorType.Arrow);
}
BeginMoveDrag(e);
};

DropClient.AddHandler(DragDrop.DragEnterEvent, DragEnterEvent);
DropClient.AddHandler(DragDrop.DragLeaveEvent, DragLeaveEvent);
DropClient.AddHandler(DragDrop.DropEvent, DragDropEvent);
}

private bool IsInResizeBorder(PointerEventArgs e, out WindowEdge edge)
{
const int boxSize = 5;
const int borderSize = 3;

if (WindowState == WindowState.FullScreen || WindowState == WindowState.Maximized) {
edge = 0;
return false;
}

Point pos = e.GetPosition(this);
if (pos.X <= boxSize && pos.Y <= boxSize) {
edge = WindowEdge.NorthWest;
return true;
}
else if (pos.X >= Bounds.Width - boxSize && pos.Y <= boxSize) {
edge = WindowEdge.NorthEast;
return true;
}
if (pos.X <= boxSize && pos.Y >= Bounds.Height - boxSize) {
edge = WindowEdge.SouthWest;
return true;
}
else if (pos.X >= Bounds.Width - boxSize && pos.Y >= Bounds.Height - boxSize) {
edge = WindowEdge.SouthEast;
return true;
}
else if (pos.Y <= borderSize) {
edge = WindowEdge.North;
return true;
}
else if (pos.Y >= Bounds.Height - borderSize) {
edge = WindowEdge.South;
return true;
}
else if (pos.X <= borderSize) {
edge = WindowEdge.West;
return true;
}
else if (pos.X >= Bounds.Width - borderSize) {
edge = WindowEdge.East;
return true;
}

edge = 0;
return false;
}

protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
if (change.Property == WindowStateProperty && change.NewValue is WindowState state) {
if (state == WindowState.Normal) {
ICON_Fullscreen.IsVisible = !(ICON_Restore.IsVisible = false);
this.GetPropertyChangedObservable(WindowStateProperty).AddClassHandler<Visual>((t, args) => {
if (args.GetNewValue<WindowState>() == WindowState.Maximized) {
ICON_Fullscreen.IsVisible = !(ICON_Restore.IsVisible = true);
if (OperatingSystem.IsWindows()) {
FixScreenSize();
}
}
else {
ICON_Fullscreen.IsVisible = !(ICON_Restore.IsVisible = true);
ICON_Fullscreen.IsVisible = !(ICON_Restore.IsVisible = false);
}
}

base.OnPropertyChanged(change);
});
}

public void DragDropEvent(object? sender, DragEventArgs e)
Expand Down Expand Up @@ -146,4 +71,20 @@ public void DragLeaveEvent(object? sender, DragEventArgs e)
{
DragFadeMask.IsVisible = false;
}

private void FixScreenSize()
{
Screen? screen = Screens.ScreenFromWindow(this);
if (screen != null) {
if (screen.WorkingArea.Height < ClientSize.Height * screen.Scaling) {
ClientSize = screen.WorkingArea.Size.ToSize(screen.Scaling);
if (Position.X < 0 || Position.Y < 0) {
Position = screen.WorkingArea.Position;
if (TryGetPlatformHandle() is IPlatformHandle platform) {
Win32Extension.FixAfterMaximizing(platform.Handle, screen);
}
}
}
}
}
}

0 comments on commit d7fc00a

Please sign in to comment.