Browse Source

windows.ui.composition compatible with acrylic blur setting.

tmp-winuicomp_with_manual_fbo
Dan Walmsley 6 years ago
parent
commit
6bcf36e23f
  1. 8
      src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs
  2. 24
      src/Windows/Avalonia.Win32/Composition/CompositionHost.cs
  3. 84
      src/Windows/Avalonia.Win32/WindowImpl.cs

8
src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs

@ -6,7 +6,7 @@ using Windows.UI.Composition.Interop;
namespace Avalonia.Win32
{
public class CompositionEglGlPlatformSurface : EglGlPlatformSurfaceBase
internal class CompositionEglGlPlatformSurface : EglGlPlatformSurfaceBase
{
private readonly EglDisplay _display;
private readonly EglContext _context;
@ -21,9 +21,11 @@ namespace Avalonia.Win32
_info = info;
}
public void AttachToCompositionTree(IntPtr hwnd)
public IBlurHost AttachToCompositionTree(IntPtr hwnd)
{
_surfaceInterop = CompositionHost.Instance.InitialiseWindowCompositionTree(hwnd, out _surface);
_surfaceInterop = CompositionHost.Instance.InitialiseWindowCompositionTree(hwnd, out _surface, out var blurHost);
return blurHost;
}
public override IGlPlatformSurfaceRenderTarget CreateGlRenderTarget()

24
src/Windows/Avalonia.Win32/Composition/CompositionHost.cs

@ -7,6 +7,26 @@ using WinRT;
namespace Avalonia.Win32
{
internal interface IBlurHost
{
void SetBlur(bool enabled);
}
internal class CompositionBlurHost : IBlurHost
{
Windows.UI.Composition.Visual _blurVisual;
public CompositionBlurHost(Windows.UI.Composition.Visual blurVisual)
{
_blurVisual = blurVisual;
}
public void SetBlur(bool enabled)
{
_blurVisual.IsVisible = enabled;
}
}
class CompositionHost
{
internal enum DISPATCHERQUEUE_THREAD_APARTMENTTYPE
@ -61,7 +81,7 @@ namespace Avalonia.Win32
_graphicsDevice = interop.CreateGraphicsDevice(display.GetDirect3DDevice());
}
public ICompositionDrawingSurfaceInterop InitialiseWindowCompositionTree(IntPtr hwnd, out Windows.UI.Composition.Visual surfaceVisual)
public ICompositionDrawingSurfaceInterop InitialiseWindowCompositionTree(IntPtr hwnd, out Windows.UI.Composition.Visual surfaceVisual, out IBlurHost blurHost)
{
var target = CreateDesktopWindowTarget(hwnd);
@ -84,6 +104,8 @@ namespace Avalonia.Win32
var blur = CreateBlur();
blurHost = new CompositionBlurHost(blur);
container.Children.InsertAtTop(blur);
var visuals = target.Root.As<ContainerVisual>().Children;

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

@ -47,6 +47,7 @@ namespace Avalonia.Win32
private Thickness _offScreenMargin;
private double _extendTitleBarHint = -1;
private bool _isUsingComposition;
private IBlurHost _blurHost;
#if USE_MANAGED_DRAG
private readonly ManagedWindowResizeDragHelper _managedDrag;
@ -114,7 +115,7 @@ namespace Avalonia.Win32
if (_isUsingComposition)
{
var cgl = new CompositionEglGlPlatformSurface(Win32GlManager.EglFeature.DeferredContext, this);
cgl.AttachToCompositionTree(_hwnd);
_blurHost = cgl.AttachToCompositionTree(_hwnd);
_gl = cgl;
@ -341,54 +342,63 @@ namespace Avalonia.Win32
private WindowTransparencyLevel Win10EnableBlur(WindowTransparencyLevel transparencyLevel)
{
bool canUseAcrylic = Win32Platform.WindowsVersion.Major > 10 || Win32Platform.WindowsVersion.Build >= 19628;
var accent = new AccentPolicy();
var accentStructSize = Marshal.SizeOf(accent);
if (transparencyLevel == WindowTransparencyLevel.AcrylicBlur && !canUseAcrylic)
if (_isUsingComposition)
{
transparencyLevel = WindowTransparencyLevel.Blur;
}
_blurHost?.SetBlur(transparencyLevel >= WindowTransparencyLevel.Blur);
switch (transparencyLevel)
return transparencyLevel;
}
else
{
default:
case WindowTransparencyLevel.None:
accent.AccentState = AccentState.ACCENT_DISABLED;
break;
bool canUseAcrylic = Win32Platform.WindowsVersion.Major > 10 || Win32Platform.WindowsVersion.Build >= 19628;
case WindowTransparencyLevel.Transparent:
accent.AccentState = AccentState.ACCENT_ENABLE_TRANSPARENTGRADIENT;
break;
var accent = new AccentPolicy();
var accentStructSize = Marshal.SizeOf(accent);
case WindowTransparencyLevel.Blur:
accent.AccentState = AccentState.ACCENT_ENABLE_BLURBEHIND;
break;
if (transparencyLevel == WindowTransparencyLevel.AcrylicBlur && !canUseAcrylic)
{
transparencyLevel = WindowTransparencyLevel.Blur;
}
case WindowTransparencyLevel.AcrylicBlur:
case (WindowTransparencyLevel.AcrylicBlur + 1): // hack-force acrylic.
accent.AccentState = AccentState.ACCENT_ENABLE_ACRYLIC;
transparencyLevel = WindowTransparencyLevel.AcrylicBlur;
break;
}
switch (transparencyLevel)
{
default:
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.AcrylicBlur + 1): // hack-force acrylic.
accent.AccentState = AccentState.ACCENT_ENABLE_ACRYLIC;
transparencyLevel = WindowTransparencyLevel.AcrylicBlur;
break;
}
accent.AccentFlags = 2;
accent.GradientColor = 0x01000000;
accent.AccentFlags = 2;
accent.GradientColor = 0x01000000;
var accentPtr = Marshal.AllocHGlobal(accentStructSize);
Marshal.StructureToPtr(accent, accentPtr, false);
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;
var data = new WindowCompositionAttributeData();
data.Attribute = WindowCompositionAttribute.WCA_ACCENT_POLICY;
data.SizeOfData = accentStructSize;
data.Data = accentPtr;
SetWindowCompositionAttribute(_hwnd, ref data);
SetWindowCompositionAttribute(_hwnd, ref data);
Marshal.FreeHGlobal(accentPtr);
Marshal.FreeHGlobal(accentPtr);
return transparencyLevel;
return transparencyLevel;
}
}
public IEnumerable<object> Surfaces => new object[] { Handle, _gl, _framebuffer };

Loading…
Cancel
Save