Browse Source

Implement transparency level hint list on win32.

Other backends have the relevant code commented-out still.
pull/11509/head
Steven Kirk 3 years ago
parent
commit
8845f239b6
  1. 168
      src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs
  2. 2
      src/Avalonia.Controls/Embedding/Offscreen/OffscreenTopLevelImpl.cs
  3. 2
      src/Avalonia.Controls/Platform/ITopLevelImpl.cs
  4. 4
      src/Avalonia.Controls/TopLevel.cs
  5. 2
      src/Avalonia.DesignerSupport/Remote/Stubs.cs
  6. 42
      src/Avalonia.Native/WindowImplBase.cs
  7. 6
      src/Avalonia.X11/X11Window.cs
  8. 12
      src/Browser/Avalonia.Browser/BrowserTopLevelImpl.cs
  9. 2
      src/Headless/Avalonia.Headless/HeadlessWindowImpl.cs
  10. 2
      src/Linux/Avalonia.LinuxFramebuffer/FramebufferToplevelImpl.cs
  11. 2
      src/Windows/Avalonia.Win32.Interop/Wpf/WpfTopLevelImpl.cs
  12. 7
      src/Windows/Avalonia.Win32/PlatformConstants.cs
  13. 1
      src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositionShared.cs
  14. 244
      src/Windows/Avalonia.Win32/WindowImpl.cs
  15. 2
      src/iOS/Avalonia.iOS/AvaloniaView.cs
  16. 2
      tests/Avalonia.UnitTests/CompositorTestServices.cs

168
src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs

@ -299,91 +299,91 @@ namespace Avalonia.Android.Platform.SkiaPlatform
public double Scaling => RenderScaling; public double Scaling => RenderScaling;
public void SetTransparencyLevelHint(WindowTransparencyLevel transparencyLevel) public void SetTransparencyLevelHint(IReadOnlyList<WindowTransparencyLevel> transparencyLevel)
{ {
if (TransparencyLevel != transparencyLevel) ////if (TransparencyLevel != transparencyLevel)
{ ////{
bool isBelowR = Build.VERSION.SdkInt < BuildVersionCodes.R; //// bool isBelowR = Build.VERSION.SdkInt < BuildVersionCodes.R;
bool isAboveR = Build.VERSION.SdkInt > BuildVersionCodes.R; //// bool isAboveR = Build.VERSION.SdkInt > BuildVersionCodes.R;
if (_view.Context is AvaloniaMainActivity activity) //// if (_view.Context is AvaloniaMainActivity activity)
{ //// {
if (transparencyLevel == WindowTransparencyLevel.AcrylicBlur || //// if (transparencyLevel == WindowTransparencyLevel.AcrylicBlur ||
transparencyLevel == WindowTransparencyLevel.Mica || //// transparencyLevel == WindowTransparencyLevel.Mica ||
transparencyLevel == WindowTransparencyLevel.None) //// transparencyLevel == WindowTransparencyLevel.None)
{ //// {
if (!isBelowR) //// if (!isBelowR)
{ //// {
activity.SetTranslucent(false); //// activity.SetTranslucent(false);
} //// }
if (isAboveR) //// if (isAboveR)
{ //// {
activity.Window?.ClearFlags(WindowManagerFlags.BlurBehind); //// activity.Window?.ClearFlags(WindowManagerFlags.BlurBehind);
var attr = activity.Window?.Attributes; //// var attr = activity.Window?.Attributes;
if (attr != null) //// if (attr != null)
{ //// {
attr.BlurBehindRadius = 0; //// attr.BlurBehindRadius = 0;
activity.Window.Attributes = attr; //// activity.Window.Attributes = attr;
} //// }
} //// }
activity.Window.SetBackgroundDrawable(new ColorDrawable(Color.White)); //// activity.Window.SetBackgroundDrawable(new ColorDrawable(Color.White));
if (transparencyLevel != WindowTransparencyLevel.None) //// if (transparencyLevel != WindowTransparencyLevel.None)
{ //// {
return; //// return;
} //// }
} //// }
if (transparencyLevel == WindowTransparencyLevel.Transparent) //// if (transparencyLevel == WindowTransparencyLevel.Transparent)
{ //// {
if (!isBelowR) //// if (!isBelowR)
{ //// {
activity.SetTranslucent(true); //// activity.SetTranslucent(true);
} //// }
if (isAboveR) //// if (isAboveR)
{ //// {
activity.Window?.ClearFlags(WindowManagerFlags.BlurBehind); //// activity.Window?.ClearFlags(WindowManagerFlags.BlurBehind);
var attr = activity.Window?.Attributes; //// var attr = activity.Window?.Attributes;
if (attr != null) //// if (attr != null)
{ //// {
attr.BlurBehindRadius = 0; //// attr.BlurBehindRadius = 0;
activity.Window.Attributes = attr; //// activity.Window.Attributes = attr;
} //// }
} //// }
activity.Window.SetBackgroundDrawable(new ColorDrawable(Color.Transparent)); //// activity.Window.SetBackgroundDrawable(new ColorDrawable(Color.Transparent));
} //// }
if (transparencyLevel == WindowTransparencyLevel.Blur) //// if (transparencyLevel == WindowTransparencyLevel.Blur)
{ //// {
if (isAboveR) //// if (isAboveR)
{ //// {
activity.SetTranslucent(true); //// activity.SetTranslucent(true);
activity.Window?.AddFlags(WindowManagerFlags.BlurBehind); //// activity.Window?.AddFlags(WindowManagerFlags.BlurBehind);
var attr = activity.Window?.Attributes; //// var attr = activity.Window?.Attributes;
if (attr != null) //// if (attr != null)
{ //// {
attr.BlurBehindRadius = 120; //// attr.BlurBehindRadius = 120;
activity.Window.Attributes = attr; //// activity.Window.Attributes = attr;
} //// }
activity.Window.SetBackgroundDrawable(new ColorDrawable(Color.Transparent)); //// activity.Window.SetBackgroundDrawable(new ColorDrawable(Color.Transparent));
} //// }
else //// else
{ //// {
activity.Window?.ClearFlags(WindowManagerFlags.BlurBehind); //// activity.Window?.ClearFlags(WindowManagerFlags.BlurBehind);
activity.Window.SetBackgroundDrawable(new ColorDrawable(Color.White)); //// activity.Window.SetBackgroundDrawable(new ColorDrawable(Color.White));
return; //// return;
} //// }
} //// }
TransparencyLevel = transparencyLevel; //// TransparencyLevel = transparencyLevel;
} //// }
} ////}
} }
public virtual object TryGetFeature(Type featureType) public virtual object TryGetFeature(Type featureType)

2
src/Avalonia.Controls/Embedding/Offscreen/OffscreenTopLevelImpl.cs

@ -89,7 +89,7 @@ namespace Avalonia.Controls.Embedding.Offscreen
public Action? LostFocus { get; set; } public Action? LostFocus { get; set; }
public abstract IMouseDevice MouseDevice { get; } public abstract IMouseDevice MouseDevice { get; }
public void SetTransparencyLevelHint(WindowTransparencyLevel transparencyLevel) { } public void SetTransparencyLevelHint(IReadOnlyList<WindowTransparencyLevel> transparencyLevel) { }
public WindowTransparencyLevel TransparencyLevel { get; private set; } public WindowTransparencyLevel TransparencyLevel { get; private set; }

2
src/Avalonia.Controls/Platform/ITopLevelImpl.cs

@ -117,7 +117,7 @@ namespace Avalonia.Platform
/// <summary> /// <summary>
/// Sets the <see cref="WindowTransparencyLevel"/> hint of the TopLevel. /// Sets the <see cref="WindowTransparencyLevel"/> hint of the TopLevel.
/// </summary> /// </summary>
void SetTransparencyLevelHint(WindowTransparencyLevel transparencyLevel); void SetTransparencyLevelHint(IReadOnlyList<WindowTransparencyLevel> transparencyLevel);
/// <summary> /// <summary>
/// Gets the current <see cref="WindowTransparencyLevel"/> of the TopLevel. /// Gets the current <see cref="WindowTransparencyLevel"/> of the TopLevel.

4
src/Avalonia.Controls/TopLevel.cs

@ -523,8 +523,8 @@ namespace Avalonia.Controls
{ {
if (PlatformImpl != null) if (PlatformImpl != null)
{ {
////PlatformImpl.SetTransparencyLevelHint( PlatformImpl.SetTransparencyLevelHint(
//// change.GetNewValue<IReadOnlyList<WindowTransparencyLevel>>() ?? Array.Empty<WindowTransparencyLevel>()); change.GetNewValue<IReadOnlyList<WindowTransparencyLevel>>() ?? Array.Empty<WindowTransparencyLevel>());
} }
} }
else if (change.Property == ActualThemeVariantProperty) else if (change.Property == ActualThemeVariantProperty)

2
src/Avalonia.DesignerSupport/Remote/Stubs.cs

@ -179,7 +179,7 @@ namespace Avalonia.DesignerSupport.Remote
public Action GotInputWhenDisabled { get; set; } public Action GotInputWhenDisabled { get; set; }
public void SetTransparencyLevelHint(WindowTransparencyLevel transparencyLevel) { } public void SetTransparencyLevelHint(IReadOnlyList<WindowTransparencyLevel> transparencyLevel) { }
public void SetWindowManagerAddShadowHint(bool enabled) public void SetWindowManagerAddShadowHint(bool enabled)
{ {

42
src/Avalonia.Native/WindowImplBase.cs

@ -485,27 +485,27 @@ namespace Avalonia.Native
_native?.BeginDragAndDropOperation(effects, point, clipboard, callback, sourceHandle); _native?.BeginDragAndDropOperation(effects, point, clipboard, callback, sourceHandle);
} }
public void SetTransparencyLevelHint(WindowTransparencyLevel transparencyLevel) public void SetTransparencyLevelHint(IReadOnlyList<WindowTransparencyLevel> transparencyLevel)
{ {
if (TransparencyLevel != transparencyLevel) ////if (TransparencyLevel != transparencyLevel)
{ ////{
if (transparencyLevel == WindowTransparencyLevel.Blur || //// if (transparencyLevel == WindowTransparencyLevel.Blur ||
transparencyLevel == WindowTransparencyLevel.AcrylicBlur || //// transparencyLevel == WindowTransparencyLevel.AcrylicBlur ||
transparencyLevel == WindowTransparencyLevel.Mica) //// transparencyLevel == WindowTransparencyLevel.Mica)
{ //// {
transparencyLevel = WindowTransparencyLevel.AcrylicBlur; //// transparencyLevel = WindowTransparencyLevel.AcrylicBlur;
} //// }
TransparencyLevel = transparencyLevel; //// TransparencyLevel = transparencyLevel;
_native.SetTransparencyMode(transparencyLevel == WindowTransparencyLevel.None //// _native.SetTransparencyMode(transparencyLevel == WindowTransparencyLevel.None
? AvnWindowTransparencyMode.Opaque //// ? AvnWindowTransparencyMode.Opaque
: transparencyLevel == WindowTransparencyLevel.Transparent //// : transparencyLevel == WindowTransparencyLevel.Transparent
? AvnWindowTransparencyMode.Transparent //// ? AvnWindowTransparencyMode.Transparent
: AvnWindowTransparencyMode.Blur); //// : AvnWindowTransparencyMode.Blur);
TransparencyLevelChanged?.Invoke(TransparencyLevel); //// TransparencyLevelChanged?.Invoke(TransparencyLevel);
} ////}
} }
public WindowTransparencyLevel TransparencyLevel { get; private set; } = WindowTransparencyLevel.None; public WindowTransparencyLevel TransparencyLevel { get; private set; } = WindowTransparencyLevel.None;

6
src/Avalonia.X11/X11Window.cs

@ -1307,8 +1307,10 @@ namespace Avalonia.X11
public IPopupPositioner? PopupPositioner { get; } public IPopupPositioner? PopupPositioner { get; }
public void SetTransparencyLevelHint(WindowTransparencyLevel transparencyLevel) => public void SetTransparencyLevelHint(IReadOnlyList<WindowTransparencyLevel> transparencyLevel)
_transparencyHelper?.SetTransparencyRequest(transparencyLevel); {
////_transparencyHelper?.SetTransparencyRequest(transparencyLevel);
}
public void SetWindowManagerAddShadowHint(bool enabled) public void SetWindowManagerAddShadowHint(bool enabled)
{ {

12
src/Browser/Avalonia.Browser/BrowserTopLevelImpl.cs

@ -223,13 +223,13 @@ namespace Avalonia.Browser
return null; return null;
} }
public void SetTransparencyLevelHint(WindowTransparencyLevel transparencyLevel) public void SetTransparencyLevelHint(IReadOnlyList<WindowTransparencyLevel> transparencyLevel)
{ {
if (transparencyLevel == WindowTransparencyLevel.None ////if (transparencyLevel == WindowTransparencyLevel.None
|| transparencyLevel == WindowTransparencyLevel.Transparent) //// || transparencyLevel == WindowTransparencyLevel.Transparent)
{ ////{
TransparencyLevel = transparencyLevel; //// TransparencyLevel = transparencyLevel;
} ////}
} }
public Size ClientSize => _clientSize; public Size ClientSize => _clientSize;

2
src/Headless/Avalonia.Headless/HeadlessWindowImpl.cs

@ -337,7 +337,7 @@ namespace Avalonia.Headless
} }
public void SetTransparencyLevelHint(WindowTransparencyLevel transparencyLevel) public void SetTransparencyLevelHint(IReadOnlyList<WindowTransparencyLevel> transparencyLevel)
{ {
} }

2
src/Linux/Avalonia.LinuxFramebuffer/FramebufferToplevelImpl.cs

@ -75,7 +75,7 @@ using Avalonia.Rendering.Composition;
public Size ScaledSize => _outputBackend.PixelSize.ToSize(RenderScaling); public Size ScaledSize => _outputBackend.PixelSize.ToSize(RenderScaling);
public void SetTransparencyLevelHint(WindowTransparencyLevel transparencyLevel) { } public void SetTransparencyLevelHint(IReadOnlyList<WindowTransparencyLevel> transparencyLevel) { }
public WindowTransparencyLevel TransparencyLevel { get; private set; } public WindowTransparencyLevel TransparencyLevel { get; private set; }

2
src/Windows/Avalonia.Win32.Interop/Wpf/WpfTopLevelImpl.cs

@ -247,7 +247,7 @@ namespace Avalonia.Win32.Interop.Wpf
public IPopupImpl CreatePopup() => null; public IPopupImpl CreatePopup() => null;
public void SetTransparencyLevelHint(WindowTransparencyLevel transparencyLevel) { } public void SetTransparencyLevelHint(IReadOnlyList<WindowTransparencyLevel> transparencyLevel) { }
public WindowTransparencyLevel TransparencyLevel { get; private set; } public WindowTransparencyLevel TransparencyLevel { get; private set; }

7
src/Windows/Avalonia.Win32/PlatformConstants.cs

@ -2,12 +2,13 @@ using System;
namespace Avalonia.Win32 namespace Avalonia.Win32
{ {
public static class PlatformConstants internal static class PlatformConstants
{ {
public const string WindowHandleType = "HWND"; public const string WindowHandleType = "HWND";
public const string CursorHandleType = "HCURSOR"; public const string CursorHandleType = "HCURSOR";
internal static readonly Version Windows8 = new Version(6, 2); public static readonly Version Windows10 = new Version(10, 0);
internal static readonly Version Windows7 = new Version(6, 1); public static readonly Version Windows8 = new Version(6, 2);
public static readonly Version Windows7 = new Version(6, 1);
} }
} }

1
src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositionShared.cs

@ -12,6 +12,7 @@ internal class WinUiCompositionShared : IDisposable
public ICompositionBrush? MicaBrush { get; } public ICompositionBrush? MicaBrush { get; }
public object SyncRoot { get; } = new(); public object SyncRoot { get; } = new();
public static readonly Version MinAcrylicVersion = new(10, 0, 15063);
public static readonly Version MinHostBackdropVersion = new(10, 0, 22000); public static readonly Version MinHostBackdropVersion = new(10, 0, 22000);
public WinUiCompositionShared(ICompositor compositor) public WinUiCompositionShared(ICompositor compositor)

244
src/Windows/Avalonia.Win32/WindowImpl.cs

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
@ -25,6 +25,7 @@ using Avalonia.Win32.WinRT.Composition;
using Avalonia.Win32.WinRT; using Avalonia.Win32.WinRT;
using static Avalonia.Win32.Interop.UnmanagedMethods; using static Avalonia.Win32.Interop.UnmanagedMethods;
using Avalonia.Input.Platform; using Avalonia.Input.Platform;
using System.Diagnostics;
namespace Avalonia.Win32 namespace Avalonia.Win32
{ {
@ -346,82 +347,119 @@ namespace Avalonia.Win32
return null; return null;
} }
public void SetTransparencyLevelHint(WindowTransparencyLevel transparencyLevel) public void SetTransparencyLevelHint(IReadOnlyList<WindowTransparencyLevel> transparencyLevels)
{ {
TransparencyLevel = EnableBlur(transparencyLevel); var windowsVersion = Win32Platform.WindowsVersion;
}
private WindowTransparencyLevel EnableBlur(WindowTransparencyLevel transparencyLevel) foreach (var level in transparencyLevels)
{
if (Win32Platform.WindowsVersion.Major >= 6)
{
if (DwmIsCompositionEnabled(out var compositionEnabled) != 0 || !compositionEnabled)
{
return WindowTransparencyLevel.None;
}
else if (Win32Platform.WindowsVersion.Major >= 10)
{
return Win10EnableBlur(transparencyLevel);
}
else if (Win32Platform.WindowsVersion.Minor >= 2)
{
return Win8xEnableBlur(transparencyLevel);
}
else
{
return Win7EnableBlur(transparencyLevel);
}
}
else
{ {
return WindowTransparencyLevel.None; if (!IsSupported(level, windowsVersion))
continue;
if (level == WindowTransparencyLevel.Transparent)
SetTransparencyTransparent(windowsVersion);
else if (level == WindowTransparencyLevel.Blur)
SetTransparencyBlur(windowsVersion);
else if (level == WindowTransparencyLevel.AcrylicBlur)
SetTransparencyAcrylicBlur(windowsVersion);
else if (level == WindowTransparencyLevel.Mica)
SetTransparencyMica(windowsVersion);
TransparencyLevel = level;
break;
} }
} }
private WindowTransparencyLevel Win7EnableBlur(WindowTransparencyLevel transparencyLevel) private bool IsSupported(WindowTransparencyLevel level, Version windowsVersion)
{ {
if (transparencyLevel == WindowTransparencyLevel.AcrylicBlur) // Only None is suppported when composition is disabled.
{ if (!_isUsingComposition)
transparencyLevel = WindowTransparencyLevel.Blur; return level == WindowTransparencyLevel.None;
}
// When composition is enabled, None is not supported because the backing visual always
// has an alpha channel
if (level == WindowTransparencyLevel.None)
return false;
// Transparent only supported on Windows 8+.
if (level == WindowTransparencyLevel.Transparent)
return windowsVersion >= PlatformConstants.Windows8;
// Blur only supported on Windows 8 and lower.
if (level == WindowTransparencyLevel.Blur)
return windowsVersion < PlatformConstants.Windows10;
// Acrylic is supported on Windows >= 10.0.15063.
if (level == WindowTransparencyLevel.AcrylicBlur)
return windowsVersion >= WinUiCompositionShared.MinAcrylicVersion;
var blurInfo = new DWM_BLURBEHIND(false); // Mica is supported on Windows >= 10.0.22000.
if (level == WindowTransparencyLevel.Mica)
return windowsVersion >= WinUiCompositionShared.MinHostBackdropVersion;
if (transparencyLevel == WindowTransparencyLevel.Blur) return false;
}
private void SetTransparencyTransparent(Version windowsVersion)
{
// Transparent only supported with composition on Windows 8+.
if (!_isUsingComposition || windowsVersion < PlatformConstants.Windows8)
return;
if (windowsVersion < PlatformConstants.Windows10)
{ {
blurInfo = new DWM_BLURBEHIND(true); // 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); DwmEnableBlurBehindWindow(_hwnd, ref blurInfo);
}
if (transparencyLevel == WindowTransparencyLevel.Transparent) private void SetTransparencyAcrylicBlur(Version windowsVersion)
{ {
return WindowTransparencyLevel.None; // Acrylic blur only supported with composition on Windows >= 10.0.15063.
} if (!_isUsingComposition || windowsVersion < WinUiCompositionShared.MinAcrylicVersion)
else return;
{
return transparencyLevel; SetUseHostBackdropBrush(true);
} _blurHost?.SetBlur(BlurEffect.Acrylic);
} }
private WindowTransparencyLevel Win8xEnableBlur(WindowTransparencyLevel transparencyLevel) private void SetTransparencyMica(Version windowsVersion)
{ {
var accent = new AccentPolicy(); // Mica only supported with composition on Windows >= 10.0.22000.
var accentStructSize = Marshal.SizeOf<AccentPolicy>(); if (!_isUsingComposition || windowsVersion < WinUiCompositionShared.MinHostBackdropVersion)
return;
if (transparencyLevel == WindowTransparencyLevel.AcrylicBlur) SetUseHostBackdropBrush(false);
{ _blurHost?.SetBlur(BlurEffect.Mica);
transparencyLevel = WindowTransparencyLevel.Blur; }
}
if (transparencyLevel == WindowTransparencyLevel.Transparent) private void SetAccentState(AccentState state)
{ {
accent.AccentState = AccentState.ACCENT_ENABLE_BLURBEHIND; var accent = new AccentPolicy();
} var accentStructSize = Marshal.SizeOf(accent);
else
{ //Some of the AccentState Enum's values have different meanings on Windows 8.x than on Windows 10
accent.AccentState = AccentState.ACCENT_DISABLED; accent.AccentState = state;
}
var accentPtr = Marshal.AllocHGlobal(accentStructSize); var accentPtr = Marshal.AllocHGlobal(accentStructSize);
Marshal.StructureToPtr(accent, accentPtr, false); Marshal.StructureToPtr(accent, accentPtr, false);
@ -432,96 +470,18 @@ namespace Avalonia.Win32
data.Data = accentPtr; data.Data = accentPtr;
SetWindowCompositionAttribute(_hwnd, ref data); SetWindowCompositionAttribute(_hwnd, ref data);
Marshal.FreeHGlobal(accentPtr); Marshal.FreeHGlobal(accentPtr);
if (transparencyLevel == WindowTransparencyLevel.Blur ||
transparencyLevel == WindowTransparencyLevel.AcrylicBlur ||
transparencyLevel == WindowTransparencyLevel.Mica)
{
Win7EnableBlur(transparencyLevel);
}
return transparencyLevel;
} }
private WindowTransparencyLevel Win10EnableBlur(WindowTransparencyLevel transparencyLevel) private void SetUseHostBackdropBrush(bool useHostBackdropBrush)
{ {
if (_isUsingComposition) if (Win32Platform.WindowsVersion < WinUiCompositionShared.MinHostBackdropVersion)
{ return;
BlurEffect effect;
if (transparencyLevel == WindowTransparencyLevel.Mica)
effect = BlurEffect.Mica;
else if (transparencyLevel == WindowTransparencyLevel.AcrylicBlur)
effect = BlurEffect.Acrylic;
else
effect = BlurEffect.None;
if (Win32Platform.WindowsVersion >= WinUiCompositionShared.MinHostBackdropVersion)
{
unsafe
{
int pvUseBackdropBrush = effect == BlurEffect.Acrylic ? 1 : 0;
DwmSetWindowAttribute(_hwnd, (int)DwmWindowAttribute.DWMWA_USE_HOSTBACKDROPBRUSH, &pvUseBackdropBrush, sizeof(int));
}
}
if (Win32Platform.WindowsVersion < WinUiCompositionShared.MinHostBackdropVersion && effect == BlurEffect.Mica)
{
effect = BlurEffect.Acrylic;
}
_blurHost?.SetBlur(effect);
return transparencyLevel; unsafe
}
else
{ {
bool canUseAcrylic = Win32Platform.WindowsVersion.Major > 10 || Win32Platform.WindowsVersion.Build >= 19628; var pvUseBackdropBrush = useHostBackdropBrush ? 1 : 0;
DwmSetWindowAttribute(_hwnd, (int)DwmWindowAttribute.DWMWA_USE_HOSTBACKDROPBRUSH, &pvUseBackdropBrush, sizeof(int));
var accent = new AccentPolicy();
var accentStructSize = Marshal.SizeOf<AccentPolicy>();
if (transparencyLevel == WindowTransparencyLevel.AcrylicBlur && !canUseAcrylic)
{
transparencyLevel = WindowTransparencyLevel.Blur;
}
if (transparencyLevel == WindowTransparencyLevel.Transparent)
{
accent.AccentState = AccentState.ACCENT_ENABLE_TRANSPARENTGRADIENT;
}
else if (transparencyLevel == WindowTransparencyLevel.Blur)
{
accent.AccentState = AccentState.ACCENT_ENABLE_BLURBEHIND;
}
else if (transparencyLevel == WindowTransparencyLevel.AcrylicBlur || transparencyLevel == WindowTransparencyLevel.Mica)
{
accent.AccentState = AccentState.ACCENT_ENABLE_ACRYLIC;
transparencyLevel = WindowTransparencyLevel.AcrylicBlur;
}
else
{
accent.AccentState = AccentState.ACCENT_DISABLED;
}
accent.AccentFlags = 2;
accent.GradientColor = 0x01000000;
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);
return transparencyLevel;
} }
} }

2
src/iOS/Avalonia.iOS/AvaloniaView.cs

@ -139,7 +139,7 @@ namespace Avalonia.iOS
return null; return null;
} }
public void SetTransparencyLevelHint(WindowTransparencyLevel transparencyLevel) public void SetTransparencyLevelHint(IReadOnlyList<WindowTransparencyLevel> transparencyLevel)
{ {
// No-op // No-op
} }

2
tests/Avalonia.UnitTests/CompositorTestServices.cs

@ -192,7 +192,7 @@ public class CompositorTestServices : IDisposable
public IMouseDevice MouseDevice { get; } = new MouseDevice(); public IMouseDevice MouseDevice { get; } = new MouseDevice();
public IPopupImpl CreatePopup() => throw new NotImplementedException(); public IPopupImpl CreatePopup() => throw new NotImplementedException();
public void SetTransparencyLevelHint(WindowTransparencyLevel transparencyLevel) public void SetTransparencyLevelHint(IReadOnlyList<WindowTransparencyLevel> transparencyLevel)
{ {
} }

Loading…
Cancel
Save