diff --git a/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs b/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs index 92a06279bb..b06708ebd2 100644 --- a/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs +++ b/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs @@ -1305,6 +1305,35 @@ namespace Avalonia.Win32.Interop [DllImport("dwmapi.dll")] public static extern int DwmIsCompositionEnabled(out bool enabled); + [StructLayout(LayoutKind.Sequential)] + internal struct RTL_OSVERSIONINFOEX + { + internal uint dwOSVersionInfoSize; + internal uint dwMajorVersion; + internal uint dwMinorVersion; + internal uint dwBuildNumber; + internal uint dwPlatformId; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] + internal string szCSDVersion; + } + + [DllImport("ntdll")] + private static extern int RtlGetVersion(out RTL_OSVERSIONINFOEX lpVersionInformation); + + internal static Version RtlGetVersion() + { + RTL_OSVERSIONINFOEX v = new RTL_OSVERSIONINFOEX(); + v.dwOSVersionInfoSize = (uint)Marshal.SizeOf(v); + if (RtlGetVersion(out v) == 0) + { + return new Version((int)v.dwMajorVersion, (int)v.dwMinorVersion, (int)v.dwBuildNumber, (int)v.dwPlatformId); + } + else + { + throw new Exception("RtlGetVersion failed!"); + } + } + [DllImport("user32.dll")] internal static extern int SetWindowCompositionAttribute(IntPtr hwnd, ref WindowCompositionAttributeData data); diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index ae9c2c9030..dd9a350b85 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -210,15 +210,15 @@ namespace Avalonia.Win32 } } - public WindowTransparencyLevel TransparencyLevel + public WindowTransparencyLevel TransparencyLevel { get => _transparencyLevel; - set + set { var oldValue = _transparencyLevel; _transparencyLevel = EnableBlur(value); - if(oldValue != _transparencyLevel) + if (oldValue != _transparencyLevel) { TransparencyLevelChanged?.Invoke(_transparencyLevel); } @@ -227,7 +227,21 @@ namespace Avalonia.Win32 private WindowTransparencyLevel EnableBlur(WindowTransparencyLevel transparencyLevel) { - if(DwmIsCompositionEnabled(out var compositionEnabled) != 0 || !compositionEnabled) + var version = RtlGetVersion(); + bool canUseTransparency = false; + bool canUseAcrylic = false; + + if (version.Major >= 10) + { + canUseTransparency = true; + + if (version.Build >= 19628) + { + canUseAcrylic = true; + } + } + + if (!canUseTransparency || DwmIsCompositionEnabled(out var compositionEnabled) != 0 || !compositionEnabled) { return WindowTransparencyLevel.None; } @@ -247,19 +261,16 @@ namespace Avalonia.Win32 break; case WindowTransparencyLevel.Blur: - accent.AccentState = AccentState.ACCENT_ENABLE_ACRYLIC; + accent.AccentState = canUseAcrylic ? AccentState.ACCENT_ENABLE_ACRYLIC : AccentState.ACCENT_ENABLE_BLURBEHIND; break; - case (WindowTransparencyLevel.Blur + 1): + case (WindowTransparencyLevel.Blur + 1): // hack force acrylic on windows 10. accent.AccentState = AccentState.ACCENT_ENABLE_ACRYLIC; break; } - var version = Environment.OSVersion; - accent.AccentFlags = 2;// (int)(AccentFlags.DrawBottomBorder | AccentFlags.DrawLeftBorder | AccentFlags.DrawRightBorder | AccentFlags.DrawTopBorder); - var bgcolor = 0x00FFFFFF; - - accent.GradientColor = bgcolor; + accent.AccentFlags = 2; + accent.GradientColor = 0x00FFFFFF; var accentPtr = Marshal.AllocHGlobal(accentStructSize); Marshal.StructureToPtr(accent, accentPtr, false); @@ -273,7 +284,6 @@ namespace Avalonia.Win32 Marshal.FreeHGlobal(accentPtr); - //todo return acheived level and check windows versions. return transparencyLevel; }