Browse Source

Replace WindowTransparencyLevel enum with list of structs

The transparency level is not yet communicated to the backends though.

Co-Authored-By: Max Katz <maxkatz6@outlook.com>
pull/11509/head
Steven Kirk 3 years ago
parent
commit
b2d7805060
  1. 2
      samples/ControlCatalog/MainView.xaml.cs
  2. 2
      samples/IntegrationTestApp/MainWindow.axaml.cs
  3. 118
      src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs
  4. 22
      src/Avalonia.Controls/ExperimentalAcrylicBorder.cs
  5. 38
      src/Avalonia.Controls/TopLevel.cs
  6. 78
      src/Avalonia.Controls/WindowTransparencyLevel.cs
  7. 6
      src/Avalonia.Native/WindowImplBase.cs
  8. 8
      src/Avalonia.X11/TransparencyHelper.cs
  9. 16
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguageParseIntrinsics.cs
  10. 4
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs
  11. 2
      src/Windows/Avalonia.Win32/TrayIconImpl.cs
  12. 54
      src/Windows/Avalonia.Win32/WindowImpl.cs
  13. 26
      tests/Avalonia.Markup.Xaml.UnitTests/Xaml/WindowTests.cs

2
samples/ControlCatalog/MainView.xaml.cs

@ -83,7 +83,7 @@ namespace ControlCatalog
if (transparencyLevels.SelectedItem is WindowTransparencyLevel selected) if (transparencyLevels.SelectedItem is WindowTransparencyLevel selected)
{ {
var topLevel = (TopLevel)this.GetVisualRoot()!; var topLevel = (TopLevel)this.GetVisualRoot()!;
topLevel.TransparencyLevelHint = selected; topLevel.TransparencyLevelHint = new[] { selected };
if (selected != WindowTransparencyLevel.None) if (selected != WindowTransparencyLevel.None)
{ {

2
samples/IntegrationTestApp/MainWindow.axaml.cs

@ -136,7 +136,7 @@ namespace IntegrationTestApp
Name = "TransparentWindow", Name = "TransparentWindow",
SystemDecorations = SystemDecorations.None, SystemDecorations = SystemDecorations.None,
Background = Brushes.Transparent, Background = Brushes.Transparent,
TransparencyLevelHint = WindowTransparencyLevel.Transparent, TransparencyLevelHint = new[] { WindowTransparencyLevel.Transparent },
WindowStartupLocation = WindowStartupLocation.CenterOwner, WindowStartupLocation = WindowStartupLocation.CenterOwner,
Width = 200, Width = 200,
Height = 200, Height = 200,

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

@ -307,78 +307,80 @@ namespace Avalonia.Android.Platform.SkiaPlatform
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)
{ {
switch (transparencyLevel) if (transparencyLevel == WindowTransparencyLevel.AcrylicBlur ||
transparencyLevel == WindowTransparencyLevel.Mica ||
transparencyLevel == WindowTransparencyLevel.None)
{ {
case WindowTransparencyLevel.AcrylicBlur: if (!isBelowR)
case WindowTransparencyLevel.ForceAcrylicBlur: {
case WindowTransparencyLevel.Mica: activity.SetTranslucent(false);
case WindowTransparencyLevel.None: }
if (!isBelowR) if (isAboveR)
{
activity.Window?.ClearFlags(WindowManagerFlags.BlurBehind);
var attr = activity.Window?.Attributes;
if (attr != null)
{ {
activity.SetTranslucent(false); attr.BlurBehindRadius = 0;
}
if (isAboveR)
{
activity.Window?.ClearFlags(WindowManagerFlags.BlurBehind);
var attr = activity.Window?.Attributes;
if (attr != null)
{
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;
} }
break; }
case WindowTransparencyLevel.Transparent:
if (!isBelowR)
{
activity.SetTranslucent(true);
}
if (isAboveR)
{
activity.Window?.ClearFlags(WindowManagerFlags.BlurBehind);
var attr = activity.Window?.Attributes; if (transparencyLevel == WindowTransparencyLevel.Transparent)
if (attr != null) {
{ if (!isBelowR)
attr.BlurBehindRadius = 0; {
activity.SetTranslucent(true);
}
if (isAboveR)
{
activity.Window?.ClearFlags(WindowManagerFlags.BlurBehind);
var attr = activity.Window?.Attributes;
if (attr != null)
{
attr.BlurBehindRadius = 0;
activity.Window.Attributes = attr; activity.Window.Attributes = attr;
}
} }
activity.Window.SetBackgroundDrawable(new ColorDrawable(Color.Transparent)); }
break; activity.Window.SetBackgroundDrawable(new ColorDrawable(Color.Transparent));
case WindowTransparencyLevel.Blur: }
if (isAboveR)
{
activity.SetTranslucent(true);
activity.Window?.AddFlags(WindowManagerFlags.BlurBehind);
var attr = activity.Window?.Attributes; if (transparencyLevel == WindowTransparencyLevel.Blur)
if (attr != null) {
{ if (isAboveR)
attr.BlurBehindRadius = 120; {
activity.SetTranslucent(true);
activity.Window?.AddFlags(WindowManagerFlags.BlurBehind);
activity.Window.Attributes = attr; var attr = activity.Window?.Attributes;
} if (attr != null)
activity.Window.SetBackgroundDrawable(new ColorDrawable(Color.Transparent));
}
else
{ {
activity.Window?.ClearFlags(WindowManagerFlags.BlurBehind); attr.BlurBehindRadius = 120;
activity.Window.SetBackgroundDrawable(new ColorDrawable(Color.White));
return; activity.Window.Attributes = attr;
} }
break; activity.Window.SetBackgroundDrawable(new ColorDrawable(Color.Transparent));
}
else
{
activity.Window?.ClearFlags(WindowManagerFlags.BlurBehind);
activity.Window.SetBackgroundDrawable(new ColorDrawable(Color.White));
return;
}
} }
TransparencyLevel = transparencyLevel; TransparencyLevel = transparencyLevel;
} }
} }

22
src/Avalonia.Controls/ExperimentalAcrylicBorder.cs

@ -56,22 +56,12 @@ namespace Avalonia.Controls
{ {
if (tl.PlatformImpl is null) if (tl.PlatformImpl is null)
return; return;
if (x == WindowTransparencyLevel.Transparent || x == WindowTransparencyLevel.None)
switch (x) Material.PlatformTransparencyCompensationLevel = tl.PlatformImpl.AcrylicCompensationLevels.TransparentLevel;
{ else if (x == WindowTransparencyLevel.Blur)
case WindowTransparencyLevel.Transparent: Material.PlatformTransparencyCompensationLevel = tl.PlatformImpl.AcrylicCompensationLevels.BlurLevel;
case WindowTransparencyLevel.None: else if (x == WindowTransparencyLevel.AcrylicBlur)
Material.PlatformTransparencyCompensationLevel = tl.PlatformImpl.AcrylicCompensationLevels.TransparentLevel; Material.PlatformTransparencyCompensationLevel = tl.PlatformImpl.AcrylicCompensationLevels.AcrylicBlurLevel;
break;
case WindowTransparencyLevel.Blur:
Material.PlatformTransparencyCompensationLevel = tl.PlatformImpl.AcrylicCompensationLevels.BlurLevel;
break;
case WindowTransparencyLevel.AcrylicBlur:
Material.PlatformTransparencyCompensationLevel = tl.PlatformImpl.AcrylicCompensationLevels.AcrylicBlurLevel;
break;
}
}); });
UpdateMaterialSubscription(); UpdateMaterialSubscription();
} }

38
src/Avalonia.Controls/TopLevel.cs

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics; using System.Diagnostics;
using Avalonia.Reactive; using Avalonia.Reactive;
@ -22,6 +23,7 @@ using Avalonia.Utilities;
using Avalonia.Input.Platform; using Avalonia.Input.Platform;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Avalonia.Metadata;
namespace Avalonia.Controls namespace Avalonia.Controls
{ {
@ -64,8 +66,8 @@ namespace Avalonia.Controls
/// <summary> /// <summary>
/// Defines the <see cref="TransparencyLevelHint"/> property. /// Defines the <see cref="TransparencyLevelHint"/> property.
/// </summary> /// </summary>
public static readonly StyledProperty<WindowTransparencyLevel> TransparencyLevelHintProperty = public static readonly StyledProperty<IReadOnlyList<WindowTransparencyLevel>> TransparencyLevelHintProperty =
AvaloniaProperty.Register<TopLevel, WindowTransparencyLevel>(nameof(TransparencyLevelHint), WindowTransparencyLevel.None); AvaloniaProperty.Register<TopLevel, IReadOnlyList<WindowTransparencyLevel>>(nameof(TransparencyLevelHint), Array.Empty<WindowTransparencyLevel>());
/// <summary> /// <summary>
/// Defines the <see cref="ActualTransparencyLevel"/> property. /// Defines the <see cref="ActualTransparencyLevel"/> property.
@ -172,7 +174,7 @@ namespace Avalonia.Controls
PlatformImpl = impl ?? throw new InvalidOperationException( PlatformImpl = impl ?? throw new InvalidOperationException(
"Could not create window implementation: maybe no windowing subsystem was initialized?"); "Could not create window implementation: maybe no windowing subsystem was initialized?");
_actualTransparencyLevel = PlatformImpl.TransparencyLevel; _actualTransparencyLevel = PlatformImpl.TransparencyLevel;
dependencyResolver ??= AvaloniaLocator.Current; dependencyResolver ??= AvaloniaLocator.Current;
@ -310,8 +312,11 @@ namespace Avalonia.Controls
/// <summary> /// <summary>
/// Gets or sets the <see cref="WindowTransparencyLevel"/> that the TopLevel should use when possible. /// Gets or sets the <see cref="WindowTransparencyLevel"/> that the TopLevel should use when possible.
/// Accepts multiple values which are applied in a fallback order.
/// For instance, with "Mica, Blur" Mica will be applied only on platforms where it is possible,
/// and Blur will be used on the rest of them. Default value is an empty array or "None".
/// </summary> /// </summary>
public WindowTransparencyLevel TransparencyLevelHint public IReadOnlyList<WindowTransparencyLevel> TransparencyLevelHint
{ {
get { return GetValue(TransparencyLevelHintProperty); } get { return GetValue(TransparencyLevelHintProperty); }
set { SetValue(TransparencyLevelHintProperty, value); } set { SetValue(TransparencyLevelHintProperty, value); }
@ -518,8 +523,8 @@ namespace Avalonia.Controls
{ {
if (PlatformImpl != null) if (PlatformImpl != null)
{ {
PlatformImpl.SetTransparencyLevelHint(change.GetNewValue<WindowTransparencyLevel>()); ////PlatformImpl.SetTransparencyLevelHint(
HandleTransparencyLevelChanged(PlatformImpl.TransparencyLevel); //// change.GetNewValue<IReadOnlyList<WindowTransparencyLevel>>() ?? Array.Empty<WindowTransparencyLevel>());
} }
} }
else if (change.Property == ActualThemeVariantProperty) else if (change.Property == ActualThemeVariantProperty)
@ -610,27 +615,11 @@ namespace Avalonia.Controls
ScalingChanged?.Invoke(this, EventArgs.Empty); ScalingChanged?.Invoke(this, EventArgs.Empty);
} }
private static bool TransparencyLevelsMatch (WindowTransparencyLevel requested, WindowTransparencyLevel received)
{
if(requested == received)
{
return true;
}
else if(requested >= WindowTransparencyLevel.Blur && received >= WindowTransparencyLevel.Blur)
{
return true;
}
return false;
}
private void HandleTransparencyLevelChanged(WindowTransparencyLevel transparencyLevel) private void HandleTransparencyLevelChanged(WindowTransparencyLevel transparencyLevel)
{ {
if(_transparencyFallbackBorder != null) if (_transparencyFallbackBorder != null)
{ {
if(transparencyLevel == WindowTransparencyLevel.None || if (transparencyLevel == WindowTransparencyLevel.None)
TransparencyLevelHint == WindowTransparencyLevel.None ||
!TransparencyLevelsMatch(TransparencyLevelHint, transparencyLevel))
{ {
_transparencyFallbackBorder.Background = TransparencyBackgroundFallback; _transparencyFallbackBorder.Background = TransparencyBackgroundFallback;
} }
@ -660,7 +649,6 @@ namespace Avalonia.Controls
return; return;
_transparencyFallbackBorder = e.NameScope.Find<Border>("PART_TransparencyFallback"); _transparencyFallbackBorder = e.NameScope.Find<Border>("PART_TransparencyFallback");
HandleTransparencyLevelChanged(PlatformImpl.TransparencyLevel); HandleTransparencyLevelChanged(PlatformImpl.TransparencyLevel);
} }

78
src/Avalonia.Controls/WindowTransparencyLevel.cs

@ -1,35 +1,51 @@
namespace Avalonia.Controls using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace Avalonia.Controls;
public readonly record struct WindowTransparencyLevel
{ {
public enum WindowTransparencyLevel private readonly string _value;
private WindowTransparencyLevel(string value)
{ {
/// <summary> _value = value;
/// The window background is Black where nothing is drawn in the window. }
/// </summary>
None, /// <summary>
/// The window background is Black where nothing is drawn in the window.
/// <summary> /// </summary>
/// The window background is Transparent where nothing is drawn in the window. public static WindowTransparencyLevel None { get; } = new(nameof(None));
/// </summary>
Transparent, /// <summary>
/// The window background is Transparent where nothing is drawn in the window.
/// <summary> /// </summary>
/// The window background is a blur-behind where nothing is drawn in the window. public static WindowTransparencyLevel Transparent { get; } = new(nameof(Transparent));
/// </summary>
Blur, /// <summary>
/// The window background is a blur-behind where nothing is drawn in the window.
/// <summary> /// </summary>
/// The window background is a blur-behind with a high blur radius. This level may fallback to Blur. public static WindowTransparencyLevel Blur { get; } = new(nameof(Blur));
/// </summary>
AcrylicBlur, /// <summary>
/// The window background is a blur-behind with a high blur radius. This level may fallback to Blur.
/// <summary> /// </summary>
/// Force acrylic on some incompatible versions of Windows 10. public static WindowTransparencyLevel AcrylicBlur { get; } = new(nameof(AcrylicBlur));
/// </summary>
ForceAcrylicBlur, /// <summary>
/// The window background is based on desktop wallpaper tint with a blur. This will only work on Windows 11
/// <summary> /// </summary>
/// The window background is based on desktop wallpaper tint with a blur. This will only work on Windows 11 public static WindowTransparencyLevel Mica { get; } = new(nameof(Mica));
/// </summary>
Mica public override string ToString()
{
return _value;
} }
} }
public class WindowTransparencyLevelCollection : ReadOnlyCollection<WindowTransparencyLevel>
{
public WindowTransparencyLevelCollection(IList<WindowTransparencyLevel> list) : base(list)
{
}
}

6
src/Avalonia.Native/WindowImplBase.cs

@ -489,8 +489,12 @@ namespace Avalonia.Native
{ {
if (TransparencyLevel != transparencyLevel) if (TransparencyLevel != transparencyLevel)
{ {
if (transparencyLevel > WindowTransparencyLevel.Transparent) if (transparencyLevel == WindowTransparencyLevel.Blur ||
transparencyLevel == WindowTransparencyLevel.AcrylicBlur ||
transparencyLevel == WindowTransparencyLevel.Mica)
{
transparencyLevel = WindowTransparencyLevel.AcrylicBlur; transparencyLevel = WindowTransparencyLevel.AcrylicBlur;
}
TransparencyLevel = transparencyLevel; TransparencyLevel = transparencyLevel;

8
src/Avalonia.X11/TransparencyHelper.cs

@ -41,7 +41,11 @@ namespace Avalonia.X11
private WindowTransparencyLevel UpdateAtomsAndGetTransparency() private WindowTransparencyLevel UpdateAtomsAndGetTransparency()
{ {
if (_requestedLevel >= WindowTransparencyLevel.Blur) var blur = _requestedLevel == WindowTransparencyLevel.Blur ||
_requestedLevel == WindowTransparencyLevel.AcrylicBlur ||
_requestedLevel == WindowTransparencyLevel.Mica;
if (blur)
{ {
if (!_blurAtomsAreSet) if (!_blurAtomsAreSet)
{ {
@ -62,7 +66,7 @@ namespace Avalonia.X11
if (!_globals.IsCompositionEnabled) if (!_globals.IsCompositionEnabled)
return WindowTransparencyLevel.None; return WindowTransparencyLevel.None;
if (_requestedLevel >= WindowTransparencyLevel.Blur && CanBlur) if (blur && CanBlur)
return WindowTransparencyLevel.Blur; return WindowTransparencyLevel.Blur;
return WindowTransparencyLevel.Transparent; return WindowTransparencyLevel.Transparent;
} }

16
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguageParseIntrinsics.cs

@ -274,6 +274,19 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
} }
} }
if (type.Equals(types.WindowTransparencyLevel))
{
foreach (var property in types.WindowTransparencyLevel.Properties)
{
if (property.PropertyType == types.WindowTransparencyLevel && property.Name.Equals(text, StringComparison.OrdinalIgnoreCase))
{
result = new XamlStaticOrTargetedReturnMethodCallNode(node, property.Getter, Enumerable.Empty<IXamlAstValueNode>());
return true;
}
}
}
if (type.Equals(types.Uri)) if (type.Equals(types.Uri))
{ {
var uriText = text.Trim(); var uriText = text.Trim();
@ -385,7 +398,8 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
result = new AvaloniaXamlIlArrayConstantAstNode(node, elementType.MakeArrayType(1), elementType, nodes); result = new AvaloniaXamlIlArrayConstantAstNode(node, elementType.MakeArrayType(1), elementType, nodes);
return true; return true;
} }
else if (type == context.Configuration.WellKnownTypes.IListOfT.MakeGenericType(elementType)) else if (type == context.Configuration.WellKnownTypes.IListOfT.MakeGenericType(elementType) ||
type == types.IReadOnlyListOfT.MakeGenericType(elementType))
{ {
var listType = context.Configuration.WellKnownTypes.IListOfT.MakeGenericType(elementType); var listType = context.Configuration.WellKnownTypes.IListOfT.MakeGenericType(elementType);
result = new AvaloniaXamlIlArrayConstantAstNode(node, listType, elementType, nodes); result = new AvaloniaXamlIlArrayConstantAstNode(node, listType, elementType, nodes);

4
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs

@ -117,6 +117,8 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
public IXamlConstructor UriConstructor { get; } public IXamlConstructor UriConstructor { get; }
public IXamlType Style { get; } public IXamlType Style { get; }
public IXamlType ControlTheme { get; } public IXamlType ControlTheme { get; }
public IXamlType WindowTransparencyLevel { get; }
public IXamlType IReadOnlyListOfT { get; }
public AvaloniaXamlIlWellKnownTypes(TransformerConfiguration cfg) public AvaloniaXamlIlWellKnownTypes(TransformerConfiguration cfg)
{ {
@ -199,6 +201,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
FontFamily = cfg.TypeSystem.GetType("Avalonia.Media.FontFamily"); FontFamily = cfg.TypeSystem.GetType("Avalonia.Media.FontFamily");
FontFamilyConstructorUriName = FontFamily.GetConstructor(new List<IXamlType> { Uri, XamlIlTypes.String }); FontFamilyConstructorUriName = FontFamily.GetConstructor(new List<IXamlType> { Uri, XamlIlTypes.String });
ThemeVariant = cfg.TypeSystem.GetType("Avalonia.Styling.ThemeVariant"); ThemeVariant = cfg.TypeSystem.GetType("Avalonia.Styling.ThemeVariant");
WindowTransparencyLevel = cfg.TypeSystem.GetType("Avalonia.Controls.WindowTransparencyLevel");
(IXamlType, IXamlConstructor) GetNumericTypeInfo(string name, IXamlType componentType, int componentCount) (IXamlType, IXamlConstructor) GetNumericTypeInfo(string name, IXamlType componentType, int componentCount)
{ {
@ -260,6 +263,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
UriConstructor = Uri.GetConstructor(new List<IXamlType>() { cfg.WellKnownTypes.String, UriKind }); UriConstructor = Uri.GetConstructor(new List<IXamlType>() { cfg.WellKnownTypes.String, UriKind });
Style = cfg.TypeSystem.GetType("Avalonia.Styling.Style"); Style = cfg.TypeSystem.GetType("Avalonia.Styling.Style");
ControlTheme = cfg.TypeSystem.GetType("Avalonia.Styling.ControlTheme"); ControlTheme = cfg.TypeSystem.GetType("Avalonia.Styling.ControlTheme");
IReadOnlyListOfT = cfg.TypeSystem.GetType("System.Collections.Generic.IReadOnlyList`1");
} }
} }

2
src/Windows/Avalonia.Win32/TrayIconImpl.cs

@ -147,7 +147,7 @@ namespace Avalonia.Win32
SystemDecorations = SystemDecorations.None, SystemDecorations = SystemDecorations.None,
SizeToContent = SizeToContent.WidthAndHeight, SizeToContent = SizeToContent.WidthAndHeight,
Background = null, Background = null,
TransparencyLevelHint = WindowTransparencyLevel.Transparent, TransparencyLevelHint = new[] { WindowTransparencyLevel.Transparent },
Content = new TrayIconMenuFlyoutPresenter() Content = new TrayIconMenuFlyoutPresenter()
{ {
ItemsSource = menuItems ItemsSource = menuItems

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

@ -435,7 +435,9 @@ namespace Avalonia.Win32
Marshal.FreeHGlobal(accentPtr); Marshal.FreeHGlobal(accentPtr);
if (transparencyLevel >= WindowTransparencyLevel.Blur) if (transparencyLevel == WindowTransparencyLevel.Blur ||
transparencyLevel == WindowTransparencyLevel.AcrylicBlur ||
transparencyLevel == WindowTransparencyLevel.Mica)
{ {
Win7EnableBlur(transparencyLevel); Win7EnableBlur(transparencyLevel);
} }
@ -447,13 +449,14 @@ namespace Avalonia.Win32
{ {
if (_isUsingComposition) if (_isUsingComposition)
{ {
var effect = transparencyLevel switch BlurEffect effect;
{
WindowTransparencyLevel.Mica => BlurEffect.Mica, if (transparencyLevel == WindowTransparencyLevel.Mica)
WindowTransparencyLevel.AcrylicBlur => BlurEffect.Acrylic, effect = BlurEffect.Mica;
WindowTransparencyLevel.Blur => BlurEffect.Acrylic, else if (transparencyLevel == WindowTransparencyLevel.AcrylicBlur)
_ => BlurEffect.None effect = BlurEffect.Acrylic;
}; else
effect = BlurEffect.None;
if (Win32Platform.WindowsVersion >= WinUiCompositionShared.MinHostBackdropVersion) if (Win32Platform.WindowsVersion >= WinUiCompositionShared.MinHostBackdropVersion)
{ {
@ -485,27 +488,22 @@ namespace Avalonia.Win32
transparencyLevel = WindowTransparencyLevel.Blur; transparencyLevel = WindowTransparencyLevel.Blur;
} }
switch (transparencyLevel) 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
{ {
default: accent.AccentState = AccentState.ACCENT_DISABLED;
case WindowTransparencyLevel.None:
accent.AccentState = AccentState.ACCENT_DISABLED;
break;
case WindowTransparencyLevel.Transparent:
accent.AccentState = AccentState.ACCENT_ENABLE_TRANSPARENTGRADIENT;
break;
case WindowTransparencyLevel.Blur:
accent.AccentState = AccentState.ACCENT_ENABLE_BLURBEHIND;
break;
case WindowTransparencyLevel.AcrylicBlur:
case WindowTransparencyLevel.ForceAcrylicBlur: // hack-force acrylic.
case WindowTransparencyLevel.Mica:
accent.AccentState = AccentState.ACCENT_ENABLE_ACRYLIC;
transparencyLevel = WindowTransparencyLevel.AcrylicBlur;
break;
} }
accent.AccentFlags = 2; accent.AccentFlags = 2;

26
tests/Avalonia.Markup.Xaml.UnitTests/Xaml/WindowTests.cs

@ -0,0 +1,26 @@
using Avalonia.Controls;
using Avalonia.UnitTests;
using Xunit;
namespace Avalonia.Markup.Xaml.UnitTests.Xaml
{
public class WindowTests : XamlTestBase
{
[Fact]
public void Can_Specify_TransparencyLevelHint()
{
using var app = UnitTestApplication.Start(TestServices.MockWindowingPlatform);
var xaml = @"<Window xmlns='https://github.com/avaloniaui' TransparencyLevelHint='Blur,Transparent,None'/>";
var target = AvaloniaRuntimeXamlLoader.Parse<Window>(xaml);
Assert.Equal(
new[]
{
WindowTransparencyLevel.Blur,
WindowTransparencyLevel.Transparent,
WindowTransparencyLevel.None,
}, target.TransparencyLevelHint);
}
}
}
Loading…
Cancel
Save