Skip to content

Commit 24789fa

Browse files
authored
Support snap layouts on Windows 11 (#467)
* Support snap layouts on Windows 11 * Don't trigger build when pushing to non-master branches
1 parent 4d04086 commit 24789fa

File tree

19 files changed

+357
-40
lines changed

19 files changed

+357
-40
lines changed

.github/workflows/build.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
name: Build
22

3-
on: [push, pull_request]
3+
on:
4+
push:
5+
branches: [ master ]
6+
pull_request:
7+
branches: [ '**' ]
48

59
jobs:
610
build:

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
<Version>0.9.5</Version>
44
<Authors>Yimeng Wu</Authors>
55
<Product>ModernWPF UI Library</Product>
6-
<LangVersion>9.0</LangVersion>
6+
<LangVersion>10.0</LangVersion>
77
</PropertyGroup>
88
</Project>

ModernWpf.SampleApp/app.manifest

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252

5353
<application xmlns="urn:schemas-microsoft-com:asm.v3">
5454
<windowsSettings>
55-
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitor</dpiAwareness>
55+
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
5656
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
5757
</windowsSettings>
5858
</application>

ModernWpf/Common/DpiScale2.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System.Windows;
2+
3+
namespace ModernWpf
4+
{
5+
internal readonly record struct DpiScale2
6+
{
7+
public DpiScale2(double dpiScaleX, double dpiScaleY)
8+
{
9+
DpiScaleX = dpiScaleX;
10+
DpiScaleY = dpiScaleY;
11+
}
12+
13+
#if NET462_OR_NEWER
14+
public DpiScale2(DpiScale dpiScale)
15+
: this(dpiScale.DpiScaleX, dpiScale.DpiScaleY)
16+
{
17+
}
18+
#endif
19+
20+
public double DpiScaleX { get; }
21+
public double DpiScaleY { get; }
22+
}
23+
}

ModernWpf/Controls/Primitives/MaximizedWindowFixer.cs

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
using MS.Win32;
2-
using Standard;
3-
using System;
4-
using System.Diagnostics;
1+
using System;
52
using System.Runtime.InteropServices;
63
using System.Windows;
74
using System.Windows.Controls;
85
using System.Windows.Interop;
9-
using System.Windows.Media;
6+
using MS.Win32;
7+
using Standard;
108
using NativeMethods = Standard.NativeMethods;
119

1210
namespace ModernWpf.Controls.Primitives
@@ -216,22 +214,12 @@ private Thickness GetMaximizedWindowBorder()
216214
return new Thickness();
217215
}
218216

219-
double dpiScaleX, dpiScaleY;
220-
#if NET462_OR_NEWER
221-
DpiScale dpi = VisualTreeHelper.GetDpi(_window);
222-
dpiScaleX = dpi.DpiScaleX;
223-
dpiScaleY = dpi.DpiScaleY;
224-
#else
225-
Matrix transformToDevice = _hwndSource.CompositionTarget.TransformToDevice;
226-
dpiScaleX = transformToDevice.M11;
227-
dpiScaleY = transformToDevice.M22;
228-
#endif
229-
217+
var dpi = _window.GetDpi();
230218
int frameWidth = NativeMethods.GetSystemMetrics(SM.CXSIZEFRAME);
231219
int frameHeight = NativeMethods.GetSystemMetrics(SM.CYSIZEFRAME);
232220
int borderPadding = NativeMethods.GetSystemMetrics(SM.CXPADDEDBORDER);
233221
Size borderSize = new Size(frameWidth + borderPadding, frameHeight + borderPadding);
234-
Size borderSizeInDips = DpiHelper.DeviceSizeToLogical(borderSize, dpiScaleX, dpiScaleY);
222+
Size borderSizeInDips = DpiHelper.DeviceSizeToLogical(borderSize, dpi.DpiScaleX, dpi.DpiScaleY);
235223

236224
return new Thickness(borderSizeInDips.Width, borderSizeInDips.Height, borderSizeInDips.Width, borderSizeInDips.Height);
237225
}

ModernWpf/Helpers/Helper.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using System;
2+
using System.Diagnostics;
23
using System.Windows;
4+
using System.Windows.Interop;
35
using System.Windows.Media;
46

57
namespace ModernWpf
@@ -80,6 +82,31 @@ public static bool HasLocalValue(this DependencyObject d, DependencyProperty dp)
8082
{
8183
return d.ReadLocalValue(dp) != DependencyProperty.UnsetValue;
8284
}
85+
86+
public static DpiScale2 GetDpi(this Window window)
87+
{
88+
if (window is null)
89+
{
90+
throw new ArgumentNullException(nameof(window));
91+
}
92+
93+
#if NET462_OR_NEWER
94+
return new DpiScale2(VisualTreeHelper.GetDpi(window));
95+
#else
96+
var hwnd = new WindowInteropHelper(window).Handle;
97+
var hwndSource = HwndSource.FromHwnd(hwnd);
98+
if (hwndSource != null)
99+
{
100+
Matrix transformToDevice = hwndSource.CompositionTarget.TransformToDevice;
101+
return new DpiScale2(transformToDevice.M11, transformToDevice.M22);
102+
}
103+
else
104+
{
105+
Debug.Fail("Should not reach here");
106+
return new DpiScale2(1, 1);
107+
}
108+
#endif
109+
}
83110
}
84111

85112
internal enum InterestPoint

ModernWpf/Helpers/OSVersionHelper.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ internal static class OSVersionHelper
1414

1515
internal static bool IsWindows10OrGreater { get; } = IsWindowsNT && _osVersion >= new Version(10, 0);
1616

17+
internal static bool IsWindows11OrGreater { get; } = IsWindowsNT && _osVersion >= new Version(10, 0, 22000);
18+
1719
private static Version GetOSVersion()
1820
{
1921
var osv = new RTL_OSVERSIONINFOEX();

ModernWpf/ModernWpf.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@
5959
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
6060
</ItemGroup>
6161

62+
<ItemGroup>
63+
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.2.1-beta">
64+
<PrivateAssets>all</PrivateAssets>
65+
</PackageReference>
66+
</ItemGroup>
67+
6268
<ItemGroup>
6369
<Page Remove="Properties\DesignTimeResources.xaml" />
6470
</ItemGroup>

ModernWpf/NativeMethods.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
WM_NCHITTEST
2+
WM_NCMOUSEMOVE
3+
WM_NCLBUTTONDOWN
4+
WM_NCLBUTTONUP
5+
WM_NCMOUSELEAVE
6+
HTCLIENT
7+
HTMAXBUTTON

ModernWpf/Standard/Utilities.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,29 @@
1212

1313
namespace Standard
1414
{
15+
using System;
1516
using System.Diagnostics.CodeAnalysis;
1617

1718
internal static partial class Utility
1819
{
20+
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
21+
public static int GET_X_LPARAM(IntPtr lParam)
22+
{
23+
return LOWORD(lParam.ToInt32());
24+
}
25+
26+
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
27+
public static int GET_Y_LPARAM(IntPtr lParam)
28+
{
29+
return HIWORD(lParam.ToInt32());
30+
}
31+
32+
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
33+
public static int HIWORD(int i)
34+
{
35+
return (short)(i >> 16);
36+
}
37+
1938
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
2039
public static int LOWORD(int i)
2140
{

0 commit comments

Comments
 (0)