From 43e1d99bdd70315aa069f867928a053b0b22eb23 Mon Sep 17 00:00:00 2001 From: Lighto Date: Fri, 14 Jul 2023 15:44:14 +0300 Subject: [PATCH 1/4] Added support for Mica Light & Dark based on Win11 --- samples/ControlCatalog/MainView.xaml | 3 +- .../WindowTransparencyLevel.cs | 9 +- .../WinRT/Composition/D2DEffects.cs | 3 + .../WinRT/Composition/WinUIEffectBase.cs | 104 ++++++++++++++++++ .../Composition/WinUiCompositedWindow.cs | 27 +++-- .../Composition/WinUiCompositionShared.cs | 8 +- .../Composition/WinUiCompositionUtils.cs | 75 ++++++++++++- src/Windows/Avalonia.Win32/WinRT/IBlurHost.cs | 3 +- .../WinRT/WinRTPropertyValue.cs | 23 +++- src/Windows/Avalonia.Win32/WindowImpl.cs | 22 +++- 10 files changed, 253 insertions(+), 24 deletions(-) diff --git a/samples/ControlCatalog/MainView.xaml b/samples/ControlCatalog/MainView.xaml index 7ed2d673790..0a1621d02ac 100644 --- a/samples/ControlCatalog/MainView.xaml +++ b/samples/ControlCatalog/MainView.xaml @@ -226,7 +226,8 @@ Transparent Blur AcrylicBlur - Mica + MicaLight + MicaDark - /// The window background is based on desktop wallpaper tint with a blur. This will only work on Windows 11 + /// The window background is based on desktop wallpaper tint with a light blur. This will only work on Windows 11 /// - public static WindowTransparencyLevel Mica { get; } = new(nameof(Mica)); + public static WindowTransparencyLevel MicaLight { get; } = new(nameof(MicaLight)); + + /// + /// The window background is based on desktop wallpaper tint with a dark blur. This will only work on Windows 11 + /// + public static WindowTransparencyLevel MicaDark { get; } = new(nameof(MicaDark)); public override string ToString() { diff --git a/src/Windows/Avalonia.Win32/WinRT/Composition/D2DEffects.cs b/src/Windows/Avalonia.Win32/WinRT/Composition/D2DEffects.cs index bef5a55b06e..98e1077885d 100644 --- a/src/Windows/Avalonia.Win32/WinRT/Composition/D2DEffects.cs +++ b/src/Windows/Avalonia.Win32/WinRT/Composition/D2DEffects.cs @@ -28,6 +28,9 @@ class D2DEffects public static readonly Guid CLSID_D2D1Border = new Guid(0x2A2D49C0, 0x4ACF, 0x43C7, 0x8C, 0x6A, 0x7C, 0x4A, 0x27, 0x87, 0x4D, 0x27); + public static readonly Guid CLSID_D2D1Opacity = + new Guid("811d79a4-de28-4454-8094-c64685f8bd4c"); + public static readonly Guid CLSID_D2D1Brightness = new Guid(0x8CEA8D1E, 0x77B0, 0x4986, 0xB3, 0xB9, 0x2F, 0x0C, 0x0E, 0xAE, 0x78, 0x87); diff --git a/src/Windows/Avalonia.Win32/WinRT/Composition/WinUIEffectBase.cs b/src/Windows/Avalonia.Win32/WinRT/Composition/WinUIEffectBase.cs index 1a922b4acd9..10dbcfcc6be 100644 --- a/src/Windows/Avalonia.Win32/WinRT/Composition/WinUIEffectBase.cs +++ b/src/Windows/Avalonia.Win32/WinRT/Composition/WinUIEffectBase.cs @@ -52,6 +52,110 @@ public override void OnUnreferencedFromNative() _sources = null; } } + + class BorderEffect : WinUIEffectBase + { + private readonly int _x; + private readonly int _y; + public override Guid EffectId => D2DEffects.CLSID_D2D1Border; + public override uint PropertyCount => 2; + + public BorderEffect(int x, int y, params IGraphicsEffectSource[] _sources):base(_sources) + { + _x = x; + _y = y; + } + + public override IPropertyValue? GetProperty(uint index) + { + if (index == 0) + return new WinRTPropertyValue((uint)_x); + if (index == 1) + return new WinRTPropertyValue((uint)_y); + return null; + } + } + + class BlendEffect : WinUIEffectBase + { + private readonly int _mode; + + public BlendEffect(int mode, params IGraphicsEffectSource[] _sources) : base(_sources) + { + _mode = mode; + } + + public override Guid EffectId => D2DEffects.CLSID_D2D1Blend; + public override uint PropertyCount => 1; + + public override IPropertyValue? GetProperty(uint index) + { + if (index == 0) + return new WinRTPropertyValue((uint)_mode); + return null; + } + } + + class CompositeStepEffect : WinUIEffectBase + { + private readonly float _mode; + + public CompositeStepEffect(int mode, params IGraphicsEffectSource[] _sources) : base(_sources) + { + _mode = mode; + } + + public override Guid EffectId => D2DEffects.CLSID_D2D1Composite; + public override uint PropertyCount => 1; + + public override IPropertyValue? GetProperty(uint index) + { + if (index == 0) + return new WinRTPropertyValue((uint)_mode); + return null; + } + } + + class OpacityEffect : WinUIEffectBase + { + private readonly float _opacity; + + public OpacityEffect(float opacity, params IGraphicsEffectSource[] _sources) : base(_sources) + { + _opacity = opacity; + } + + public override Guid EffectId => D2DEffects.CLSID_D2D1Opacity; + public override uint PropertyCount => 1; + + public override IPropertyValue? GetProperty(uint index) + { + if (index == 0) + return new WinRTPropertyValue(_opacity); + return null; + } + } + + class ColorSourceEffect : WinUIEffectBase + { + private readonly float[] _color; + + public ColorSourceEffect(float[] color) + { + _color = color; + } + + public override Guid EffectId => D2DEffects.CLSID_D2D1Flood; + public override uint PropertyCount => 1; + + public override IPropertyValue? GetProperty(uint index) + { + if (index == 0) + return new WinRTPropertyValue(_color); + return null; + } + } + internal class WinUIGaussianBlurEffect : WinUIEffectBase { diff --git a/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositedWindow.cs b/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositedWindow.cs index 2f22ba99f97..d87c8d13619 100644 --- a/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositedWindow.cs +++ b/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositedWindow.cs @@ -12,7 +12,8 @@ internal class WinUiCompositedWindow : IDisposable public EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo WindowInfo { get; } private readonly WinUiCompositionShared _shared; private readonly ICompositionRoundedRectangleGeometry? _compositionRoundedRectangleGeometry; - private readonly IVisual? _mica; + private readonly IVisual? _micaLight; + private readonly IVisual? _micaDark; private readonly IVisual _blur; private readonly IVisual _visual; private PixelSize _size; @@ -25,7 +26,8 @@ public void Dispose() { _compositionRoundedRectangleGeometry?.Dispose(); _blur.Dispose(); - _mica?.Dispose(); + _micaLight?.Dispose(); + _micaDark?.Dispose(); _visual.Dispose(); _surfaceBrush.Dispose(); _target.Dispose(); @@ -50,14 +52,20 @@ public WinUiCompositedWindow(EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInf _target.SetRoot(containerVisual); _blur = WinUiCompositionUtils.CreateBlurVisual(shared.Compositor, shared.BlurBrush); - if (shared.MicaBrush != null) + if (shared.MicaBrushLight != null) { - _mica = WinUiCompositionUtils.CreateBlurVisual(shared.Compositor, shared.MicaBrush); - containerChildren.InsertAtTop(_mica); + _micaLight = WinUiCompositionUtils.CreateBlurVisual(shared.Compositor, shared.MicaBrushLight); + containerChildren.InsertAtTop(_micaLight); + } + + if (shared.MicaBrushDark != null) + { + _micaDark = WinUiCompositionUtils.CreateBlurVisual(shared.Compositor, shared.MicaBrushDark); + containerChildren.InsertAtTop(_micaDark); } _compositionRoundedRectangleGeometry = - WinUiCompositionUtils.ClipVisual(shared.Compositor, backdropCornerRadius, _blur, _mica); + WinUiCompositionUtils.ClipVisual(shared.Compositor, backdropCornerRadius, _blur, _micaLight, _micaDark); containerChildren.InsertAtTop(_blur); using var spriteVisual = shared.Compositor.CreateSpriteVisual(); @@ -79,12 +87,13 @@ public void SetBlur(BlurEffect blurEffect) { lock (_shared.SyncRoot) { - _blur.SetIsVisible(blurEffect == BlurEffect.Acrylic - || blurEffect == BlurEffect.Mica && _mica == null ? + || (blurEffect == BlurEffect.MicaLight && _micaLight == null) || + (blurEffect == BlurEffect.MicaDark && _micaDark == null) ? 1 : 0); - _mica?.SetIsVisible(blurEffect == BlurEffect.Mica ? 1 : 0); + _micaLight?.SetIsVisible(blurEffect == BlurEffect.MicaLight ? 1 : 0); + _micaDark?.SetIsVisible(blurEffect == BlurEffect.MicaDark ? 1 : 0); } } diff --git a/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositionShared.cs b/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositionShared.cs index b3a328d0978..5c7f490710a 100644 --- a/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositionShared.cs +++ b/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositionShared.cs @@ -9,6 +9,8 @@ internal class WinUiCompositionShared : IDisposable public ICompositor5 Compositor5 { get; } public ICompositorDesktopInterop DesktopInterop { get; } public ICompositionBrush BlurBrush { get; } + public ICompositionBrush? MicaBrushLight { get; } + public ICompositionBrush? MicaBrushDark { get; } public ICompositionBrush? MicaBrush { get; } public object SyncRoot { get; } = new(); @@ -21,14 +23,16 @@ public WinUiCompositionShared(ICompositor compositor) Compositor = compositor.CloneReference(); Compositor5 = compositor.QueryInterface(); BlurBrush = WinUiCompositionUtils.CreateAcrylicBlurBackdropBrush(compositor); - MicaBrush = WinUiCompositionUtils.CreateMicaBackdropBrush(compositor); + MicaBrushLight = WinUiCompositionUtils.CreateMicaBackdropBrush(compositor, 242, 0.6f); + MicaBrushDark = WinUiCompositionUtils.CreateMicaBackdropBrush(compositor, 32, 0.8f); DesktopInterop = compositor.QueryInterface(); } public void Dispose() { BlurBrush.Dispose(); - MicaBrush?.Dispose(); + MicaBrushLight?.Dispose(); + MicaBrushDark?.Dispose(); DesktopInterop.Dispose(); Compositor.Dispose(); Compositor5.Dispose(); diff --git a/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositionUtils.cs b/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositionUtils.cs index 7b970868df0..1a130698ee9 100644 --- a/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositionUtils.cs +++ b/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositionUtils.cs @@ -1,3 +1,4 @@ +using System; using System.Numerics; using MicroCom.Runtime; @@ -5,16 +6,75 @@ namespace Avalonia.Win32.WinRT.Composition; internal static class WinUiCompositionUtils { - public static ICompositionBrush? CreateMicaBackdropBrush(ICompositor compositor) + public static ICompositionBrush? CreateMicaBackdropBrush(ICompositor compositor, float color, float opacity) { if (Win32Platform.WindowsVersion.Build < 22000) return null; + using var backDropParameterFactory = + NativeWinRTMethods.CreateActivationFactory( + "Windows.UI.Composition.CompositionEffectSourceParameter"); + + + var tint = new[] { color / 255f, color / 255f, color / 255f, 255f / 255f }; + + using var tintColorEffect = new ColorSourceEffect(tint); + + + using var tintOpacityEffect = new OpacityEffect(1.0f, tintColorEffect); + using var tintOpacityEffectFactory = compositor.CreateEffectFactory(tintOpacityEffect); + using var tintOpacityEffectBrushEffect = tintOpacityEffectFactory.CreateBrush(); + using var tintOpacityEffectBrush = tintOpacityEffectBrushEffect.QueryInterface(); + + using var luminosityColorEffect = new ColorSourceEffect(tint); + + using var luminosityOpacityEffect = new OpacityEffect(opacity, luminosityColorEffect); + using var luminosityOpacityEffectFactory = compositor.CreateEffectFactory(luminosityOpacityEffect); + using var luminosityOpacityEffectBrushEffect = luminosityOpacityEffectFactory.CreateBrush(); + using var luminosityOpacityEffectBrush = + luminosityOpacityEffectBrushEffect.QueryInterface(); + + + // using var backDropParameterAsSource = GetParameterSource("BlurredWallpaperBackdrop", backDropParameterFactory, out var backdropHandle); + // using var backdropCompositionBrsuh = backDropParameterAsSource.QueryInterface(); using var compositorWithBlurredWallpaperBackdropBrush = compositor.QueryInterface(); using var blurredWallpaperBackdropBrush = compositorWithBlurredWallpaperBackdropBrush?.TryCreateBlurredWallpaperBackdropBrush(); - return blurredWallpaperBackdropBrush?.QueryInterface(); + using var micaBackdropBrush = blurredWallpaperBackdropBrush?.QueryInterface(); + + + using var backgroundParameterAsSource = + GetParameterSource("Background", backDropParameterFactory, out var backgroundHandle); + using var foregroundParameterAsSource = + GetParameterSource("Foreground", backDropParameterFactory, out var foregroundHandle); + + using var luminosityBlendEffect = + new BlendEffect(23, backgroundParameterAsSource, foregroundParameterAsSource); + using var luminosityBlendEffectFactory = compositor.CreateEffectFactory(luminosityBlendEffect); + using var luminosityBlendEffectBrush = luminosityBlendEffectFactory.CreateBrush(); + using var luminosityBlendEffectBrush1 = luminosityBlendEffectBrush.QueryInterface(); + luminosityBlendEffectBrush.SetSourceParameter(backgroundHandle, micaBackdropBrush); + luminosityBlendEffectBrush.SetSourceParameter(foregroundHandle, luminosityOpacityEffectBrush); + + + using var backgroundParameterAsSource1 = + GetParameterSource("Background", backDropParameterFactory, out var backgroundHandle1); + using var foregroundParameterAsSource1 = + GetParameterSource("Foreground", backDropParameterFactory, out var foregroundHandle1); + + using var colorBlendEffect = + new BlendEffect(22, backgroundParameterAsSource1, foregroundParameterAsSource1); + using var colorBlendEffectFactory = compositor.CreateEffectFactory(colorBlendEffect); + using var colorBlendEffectBrush = colorBlendEffectFactory.CreateBrush(); + colorBlendEffectBrush.SetSourceParameter(backgroundHandle1, luminosityBlendEffectBrush1); + colorBlendEffectBrush.SetSourceParameter(foregroundHandle1, tintOpacityEffectBrush); + + + // colorBlendEffectBrush.SetSourceParameter(backgroundHandle, micaBackdropBrush); + + using var micaBackdropBrush1 = colorBlendEffectBrush.QueryInterface(); + return micaBackdropBrush1.CloneReference(); } public static ICompositionBrush CreateAcrylicBlurBackdropBrush(ICompositor compositor) @@ -97,4 +157,15 @@ public static ICompositionBrush CreateBackdropBrush(ICompositor compositor) brush?.Dispose(); } } + + private static IGraphicsEffectSource GetParameterSource(string name, + ICompositionEffectSourceParameterFactory backDropParameterFactory, out IntPtr handle) + { + var backdropString = new HStringInterop(name); + var backDropParameter = + backDropParameterFactory.Create(backdropString.Handle); + var backDropParameterAsSource = backDropParameter.QueryInterface(); + handle = backdropString.Handle; + return backDropParameterAsSource; + } } diff --git a/src/Windows/Avalonia.Win32/WinRT/IBlurHost.cs b/src/Windows/Avalonia.Win32/WinRT/IBlurHost.cs index a3918d9ae6c..5f2e752af88 100644 --- a/src/Windows/Avalonia.Win32/WinRT/IBlurHost.cs +++ b/src/Windows/Avalonia.Win32/WinRT/IBlurHost.cs @@ -4,7 +4,8 @@ internal enum BlurEffect { None, Acrylic, - Mica + MicaLight, + MicaDark } internal interface IBlurHost diff --git a/src/Windows/Avalonia.Win32/WinRT/WinRTPropertyValue.cs b/src/Windows/Avalonia.Win32/WinRT/WinRTPropertyValue.cs index 684e7ff7b5f..8874902d4e0 100644 --- a/src/Windows/Avalonia.Win32/WinRT/WinRTPropertyValue.cs +++ b/src/Windows/Avalonia.Win32/WinRT/WinRTPropertyValue.cs @@ -1,4 +1,5 @@ using System; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace Avalonia.Win32.WinRT @@ -16,7 +17,15 @@ public WinRTPropertyValue(uint u) UInt32 = u; Type = PropertyType.UInt32; } - + + public WinRTPropertyValue(float[] uiColor) + { + Type = PropertyType.SingleArray; + _singleArray = uiColor; + } + + private readonly float[]? _singleArray; + public PropertyType Type { get; } public int IsNumericScalar { get; } public byte UInt8 { get; } @@ -62,7 +71,17 @@ public WinRTPropertyValue(uint u) public unsafe ulong* GetUInt64Array(uint* __valueSize) => throw NotImplemented; - public unsafe float* GetSingleArray(uint* __valueSize) => throw NotImplemented; + public unsafe float* GetSingleArray(uint* __valueSize) + { + if (_singleArray == null) + throw NotImplemented; + *__valueSize = (uint)_singleArray.Length; + var allocCoTaskMem = Marshal.AllocCoTaskMem(_singleArray.Length * Unsafe.SizeOf()); + Marshal.Copy(_singleArray, 0, allocCoTaskMem, _singleArray.Length); + float* s = (float*)allocCoTaskMem; + + return s; + } public unsafe double* GetDoubleArray(uint* __valueSize) => throw NotImplemented; diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index 057cdb2db0d..2b16bbe275f 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -374,8 +374,10 @@ public void SetTransparencyLevelHint(IReadOnlyList tran SetTransparencyBlur(windowsVersion); else if (level == WindowTransparencyLevel.AcrylicBlur) SetTransparencyAcrylicBlur(windowsVersion); - else if (level == WindowTransparencyLevel.Mica) - SetTransparencyMica(windowsVersion); + else if (level == WindowTransparencyLevel.MicaLight) + SetTransparencyMicaLight(windowsVersion); + else if (level == WindowTransparencyLevel.MicaDark) + SetTransparencyMicaDark(windowsVersion); TransparencyLevel = level; return; @@ -418,7 +420,7 @@ private bool IsSupported(WindowTransparencyLevel level, Version windowsVersion) return windowsVersion >= WinUiCompositionShared.MinAcrylicVersion; // Mica is supported on Windows >= 10.0.22000. - if (level == WindowTransparencyLevel.Mica) + if (level == WindowTransparencyLevel.MicaLight || level == WindowTransparencyLevel.MicaDark) return windowsVersion >= WinUiCompositionShared.MinHostBackdropVersion; return false; @@ -467,14 +469,24 @@ private void SetTransparencyAcrylicBlur(Version windowsVersion) _blurHost?.SetBlur(BlurEffect.Acrylic); } - private void SetTransparencyMica(Version windowsVersion) + private void SetTransparencyMicaLight(Version windowsVersion) { // Mica only supported with composition on Windows >= 10.0.22000. if (!_isUsingComposition || windowsVersion < WinUiCompositionShared.MinHostBackdropVersion) return; SetUseHostBackdropBrush(false); - _blurHost?.SetBlur(BlurEffect.Mica); + _blurHost?.SetBlur(BlurEffect.MicaLight); + } + + private void SetTransparencyMicaDark(Version windowsVersion) + { + // Mica only supported with composition on Windows >= 10.0.22000. + if (!_isUsingComposition || windowsVersion < WinUiCompositionShared.MinHostBackdropVersion) + return; + + SetUseHostBackdropBrush(false); + _blurHost?.SetBlur(BlurEffect.MicaDark); } private void SetAccentState(AccentState state) From 432dafac91dc4cb61ffd338f7d8afcf5d4ab6540 Mon Sep 17 00:00:00 2001 From: Lighto Date: Fri, 14 Jul 2023 18:38:35 +0300 Subject: [PATCH 2/4] Removed unused old property --- .../Avalonia.Win32/WinRT/Composition/WinUiCompositionShared.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositionShared.cs b/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositionShared.cs index 5c7f490710a..7a775afb3a2 100644 --- a/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositionShared.cs +++ b/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositionShared.cs @@ -11,7 +11,6 @@ internal class WinUiCompositionShared : IDisposable public ICompositionBrush BlurBrush { get; } public ICompositionBrush? MicaBrushLight { get; } public ICompositionBrush? MicaBrushDark { get; } - public ICompositionBrush? MicaBrush { get; } public object SyncRoot { get; } = new(); public static readonly Version MinWinCompositionVersion = new(10, 0, 17134); From 55c03069b1e9cf681cde74a476038118296c340f Mon Sep 17 00:00:00 2001 From: Lighto Date: Sat, 15 Jul 2023 22:18:59 +0300 Subject: [PATCH 3/4] Changed Mica dark/light based on theme --- samples/ControlCatalog/MainView.xaml | 3 +- .../WindowTransparencyLevel.cs | 9 ++--- .../Composition/WinUiCompositedWindow.cs | 3 -- src/Windows/Avalonia.Win32/WindowImpl.cs | 33 +++++++++---------- 4 files changed, 19 insertions(+), 29 deletions(-) diff --git a/samples/ControlCatalog/MainView.xaml b/samples/ControlCatalog/MainView.xaml index 0a1621d02ac..7ed2d673790 100644 --- a/samples/ControlCatalog/MainView.xaml +++ b/samples/ControlCatalog/MainView.xaml @@ -226,8 +226,7 @@ Transparent Blur AcrylicBlur - MicaLight - MicaDark + Mica - /// The window background is based on desktop wallpaper tint with a light blur. This will only work on Windows 11 + /// The window background is based on desktop wallpaper tint with a blur. This will only work on Windows 11 /// - public static WindowTransparencyLevel MicaLight { get; } = new(nameof(MicaLight)); + public static WindowTransparencyLevel Mica { get; } = new(nameof(Mica)); - /// - /// The window background is based on desktop wallpaper tint with a dark blur. This will only work on Windows 11 - /// - public static WindowTransparencyLevel MicaDark { get; } = new(nameof(MicaDark)); - public override string ToString() { return _value; diff --git a/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositedWindow.cs b/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositedWindow.cs index d87c8d13619..d720e525d3a 100644 --- a/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositedWindow.cs +++ b/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositedWindow.cs @@ -76,9 +76,6 @@ public WinUiCompositedWindow(EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInf using var compositionBrush = _surfaceBrush.QueryInterface(); spriteVisual.SetBrush(compositionBrush); _target.SetRoot(containerVisual); - - - } public void SetSurface(ICompositionSurface surface) => _surfaceBrush.SetSurface(surface); diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index 2b16bbe275f..044c2cad67e 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -106,6 +106,7 @@ internal partial class WindowImpl : IWindowImpl, EglGlPlatformSurface.IEglWindow private static POINTER_PEN_INFO[]? s_historyPenInfos; private static POINTER_INFO[]? s_historyInfos; private static MOUSEMOVEPOINT[]? s_mouseHistoryInfos; + private PlatformThemeVariant _currentThemeVariant; public WindowImpl() { @@ -374,10 +375,8 @@ public void SetTransparencyLevelHint(IReadOnlyList tran SetTransparencyBlur(windowsVersion); else if (level == WindowTransparencyLevel.AcrylicBlur) SetTransparencyAcrylicBlur(windowsVersion); - else if (level == WindowTransparencyLevel.MicaLight) - SetTransparencyMicaLight(windowsVersion); - else if (level == WindowTransparencyLevel.MicaDark) - SetTransparencyMicaDark(windowsVersion); + else if (level == WindowTransparencyLevel.Mica) + SetTransparencyMica(windowsVersion); TransparencyLevel = level; return; @@ -420,7 +419,7 @@ private bool IsSupported(WindowTransparencyLevel level, Version windowsVersion) return windowsVersion >= WinUiCompositionShared.MinAcrylicVersion; // Mica is supported on Windows >= 10.0.22000. - if (level == WindowTransparencyLevel.MicaLight || level == WindowTransparencyLevel.MicaDark) + if (level == WindowTransparencyLevel.Mica) return windowsVersion >= WinUiCompositionShared.MinHostBackdropVersion; return false; @@ -469,24 +468,19 @@ private void SetTransparencyAcrylicBlur(Version windowsVersion) _blurHost?.SetBlur(BlurEffect.Acrylic); } - private void SetTransparencyMicaLight(Version windowsVersion) + private void SetTransparencyMica(Version windowsVersion) { // Mica only supported with composition on Windows >= 10.0.22000. if (!_isUsingComposition || windowsVersion < WinUiCompositionShared.MinHostBackdropVersion) return; SetUseHostBackdropBrush(false); - _blurHost?.SetBlur(BlurEffect.MicaLight); - } - - private void SetTransparencyMicaDark(Version windowsVersion) - { - // Mica only supported with composition on Windows >= 10.0.22000. - if (!_isUsingComposition || windowsVersion < WinUiCompositionShared.MinHostBackdropVersion) - return; - - SetUseHostBackdropBrush(false); - _blurHost?.SetBlur(BlurEffect.MicaDark); + _blurHost?.SetBlur(_currentThemeVariant switch + { + PlatformThemeVariant.Light => BlurEffect.MicaLight, + PlatformThemeVariant.Dark => BlurEffect.MicaDark, + _ => throw new ArgumentOutOfRangeException() + }); } private void SetAccentState(AccentState state) @@ -790,6 +784,7 @@ public void SetTopmost(bool value) public unsafe void SetFrameThemeVariant(PlatformThemeVariant themeVariant) { + _currentThemeVariant = themeVariant; if (Win32Platform.WindowsVersion.Build >= 22000) { var pvUseBackdropBrush = themeVariant == PlatformThemeVariant.Dark ? 1 : 0; @@ -798,6 +793,10 @@ public unsafe void SetFrameThemeVariant(PlatformThemeVariant themeVariant) (int)DwmWindowAttribute.DWMWA_USE_IMMERSIVE_DARK_MODE, &pvUseBackdropBrush, sizeof(int)); + if (TransparencyLevel == WindowTransparencyLevel.Mica) + { + SetTransparencyMica(Win32Platform.WindowsVersion); + } } } From 7a0e0c41a40baf60cce214ee6756f95ca75fd7a8 Mon Sep 17 00:00:00 2001 From: Lighto Date: Sat, 15 Jul 2023 22:20:50 +0300 Subject: [PATCH 4/4] Removed unnecessary spaces --- src/Avalonia.Controls/WindowTransparencyLevel.cs | 2 +- .../WinRT/Composition/WinUiCompositionUtils.cs | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/Avalonia.Controls/WindowTransparencyLevel.cs b/src/Avalonia.Controls/WindowTransparencyLevel.cs index 9604a7ef5c0..bce6e21e684 100644 --- a/src/Avalonia.Controls/WindowTransparencyLevel.cs +++ b/src/Avalonia.Controls/WindowTransparencyLevel.cs @@ -36,7 +36,7 @@ private WindowTransparencyLevel(string value) /// 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)); - + public override string ToString() { return _value; diff --git a/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositionUtils.cs b/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositionUtils.cs index 1a130698ee9..29c1e1fe278 100644 --- a/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositionUtils.cs +++ b/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositionUtils.cs @@ -33,10 +33,7 @@ internal static class WinUiCompositionUtils using var luminosityOpacityEffectBrushEffect = luminosityOpacityEffectFactory.CreateBrush(); using var luminosityOpacityEffectBrush = luminosityOpacityEffectBrushEffect.QueryInterface(); - - - // using var backDropParameterAsSource = GetParameterSource("BlurredWallpaperBackdrop", backDropParameterFactory, out var backdropHandle); - // using var backdropCompositionBrsuh = backDropParameterAsSource.QueryInterface(); + using var compositorWithBlurredWallpaperBackdropBrush = compositor.QueryInterface(); using var blurredWallpaperBackdropBrush =