diff --git a/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs b/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs index e58abcadf0..ce42227292 100644 --- a/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs +++ b/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs @@ -1827,6 +1827,9 @@ namespace Avalonia.Win32.Interop return result; } + [DllImport("user32.dll")] + internal static extern int SetWindowCompositionAttribute(IntPtr hwnd, ref WindowCompositionAttributeData data); + [Flags] public enum GCS : uint { diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index 3fc2751e43..057cdb2db0 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -371,7 +371,7 @@ namespace Avalonia.Win32 if (level == WindowTransparencyLevel.Transparent) SetTransparencyTransparent(windowsVersion); else if (level == WindowTransparencyLevel.Blur) - continue; // Unsupported on all versions (unreachable) + SetTransparencyBlur(windowsVersion); else if (level == WindowTransparencyLevel.AcrylicBlur) SetTransparencyAcrylicBlur(windowsVersion); else if (level == WindowTransparencyLevel.Mica) @@ -409,9 +409,9 @@ namespace Avalonia.Win32 if (level == WindowTransparencyLevel.Transparent) return windowsVersion >= PlatformConstants.Windows8; - // Support for legacy, undocumented DWM blur has been removed. + // Blur only supported on Windows 8 and lower. if (level == WindowTransparencyLevel.Blur) - return false; + return windowsVersion < PlatformConstants.Windows10; // Acrylic is supported on Windows >= 10.0.15063. if (level == WindowTransparencyLevel.AcrylicBlur) @@ -426,14 +426,37 @@ namespace Avalonia.Win32 private void SetTransparencyTransparent(Version windowsVersion) { - // Transparent only supported with composition on Windows 10+. - if (!_isUsingComposition || windowsVersion < PlatformConstants.Windows10) + // Transparent only supported with composition on Windows 8+. + if (!_isUsingComposition || windowsVersion < PlatformConstants.Windows8) return; + if (windowsVersion < PlatformConstants.Windows10) + { + // Some of the AccentState Enum's values have different meanings on Windows 8.x than on + // Windows 10, hence using ACCENT_ENABLE_BLURBEHIND to disable blurbehind ¯\_(ツ)_/¯. + // Hey, I'm just porting what was here before. + SetAccentState(AccentState.ACCENT_ENABLE_BLURBEHIND); + var blurInfo = new DWM_BLURBEHIND(false); + DwmEnableBlurBehindWindow(_hwnd, ref blurInfo); + } + SetUseHostBackdropBrush(false); _blurHost?.SetBlur(BlurEffect.None); } + private void SetTransparencyBlur(Version windowsVersion) + { + // Blur only supported with composition on Windows 8 and lower. + if (!_isUsingComposition || windowsVersion >= PlatformConstants.Windows10) + return; + + // Some of the AccentState Enum's values have different meanings on Windows 8.x than on + // Windows 10. + SetAccentState(AccentState.ACCENT_DISABLED); + var blurInfo = new DWM_BLURBEHIND(true); + DwmEnableBlurBehindWindow(_hwnd, ref blurInfo); + } + private void SetTransparencyAcrylicBlur(Version windowsVersion) { // Acrylic blur only supported with composition on Windows >= 10.0.15063. @@ -454,6 +477,26 @@ namespace Avalonia.Win32 _blurHost?.SetBlur(BlurEffect.Mica); } + private void SetAccentState(AccentState state) + { + var accent = new AccentPolicy(); + var accentStructSize = Marshal.SizeOf(accent); + + //Some of the AccentState Enum's values have different meanings on Windows 8.x than on Windows 10 + accent.AccentState = state; + + var accentPtr = Marshal.AllocHGlobal(accentStructSize); + Marshal.StructureToPtr(accent, accentPtr, false); + + var data = new WindowCompositionAttributeData(); + data.Attribute = WindowCompositionAttribute.WCA_ACCENT_POLICY; + data.SizeOfData = accentStructSize; + data.Data = accentPtr; + + SetWindowCompositionAttribute(_hwnd, ref data); + Marshal.FreeHGlobal(accentPtr); + } + private void SetUseHostBackdropBrush(bool useHostBackdropBrush) { if (Win32Platform.WindowsVersion < WinUiCompositionShared.MinHostBackdropVersion)