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 namespace Avalonia.Win32
{ {
public class CompositionEglGlPlatformSurface : EglGlPlatformSurfaceBase internal class CompositionEglGlPlatformSurface : EglGlPlatformSurfaceBase
{ {
private readonly EglDisplay _display; private readonly EglDisplay _display;
private readonly EglContext _context; private readonly EglContext _context;
@ -21,9 +21,11 @@ namespace Avalonia.Win32
_info = info; _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() public override IGlPlatformSurfaceRenderTarget CreateGlRenderTarget()

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

@ -7,6 +7,26 @@ using WinRT;
namespace Avalonia.Win32 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 class CompositionHost
{ {
internal enum DISPATCHERQUEUE_THREAD_APARTMENTTYPE internal enum DISPATCHERQUEUE_THREAD_APARTMENTTYPE
@ -61,7 +81,7 @@ namespace Avalonia.Win32
_graphicsDevice = interop.CreateGraphicsDevice(display.GetDirect3DDevice()); _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); var target = CreateDesktopWindowTarget(hwnd);
@ -84,6 +104,8 @@ namespace Avalonia.Win32
var blur = CreateBlur(); var blur = CreateBlur();
blurHost = new CompositionBlurHost(blur);
container.Children.InsertAtTop(blur); container.Children.InsertAtTop(blur);
var visuals = target.Root.As<ContainerVisual>().Children; 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 Thickness _offScreenMargin;
private double _extendTitleBarHint = -1; private double _extendTitleBarHint = -1;
private bool _isUsingComposition; private bool _isUsingComposition;
private IBlurHost _blurHost;
#if USE_MANAGED_DRAG #if USE_MANAGED_DRAG
private readonly ManagedWindowResizeDragHelper _managedDrag; private readonly ManagedWindowResizeDragHelper _managedDrag;
@ -114,7 +115,7 @@ namespace Avalonia.Win32
if (_isUsingComposition) if (_isUsingComposition)
{ {
var cgl = new CompositionEglGlPlatformSurface(Win32GlManager.EglFeature.DeferredContext, this); var cgl = new CompositionEglGlPlatformSurface(Win32GlManager.EglFeature.DeferredContext, this);
cgl.AttachToCompositionTree(_hwnd); _blurHost = cgl.AttachToCompositionTree(_hwnd);
_gl = cgl; _gl = cgl;
@ -341,54 +342,63 @@ namespace Avalonia.Win32
private WindowTransparencyLevel Win10EnableBlur(WindowTransparencyLevel transparencyLevel) private WindowTransparencyLevel Win10EnableBlur(WindowTransparencyLevel transparencyLevel)
{ {
bool canUseAcrylic = Win32Platform.WindowsVersion.Major > 10 || Win32Platform.WindowsVersion.Build >= 19628; if (_isUsingComposition)
var accent = new AccentPolicy();
var accentStructSize = Marshal.SizeOf(accent);
if (transparencyLevel == WindowTransparencyLevel.AcrylicBlur && !canUseAcrylic)
{ {
transparencyLevel = WindowTransparencyLevel.Blur; _blurHost?.SetBlur(transparencyLevel >= WindowTransparencyLevel.Blur);
}
switch (transparencyLevel) return transparencyLevel;
}
else
{ {
default: bool canUseAcrylic = Win32Platform.WindowsVersion.Major > 10 || Win32Platform.WindowsVersion.Build >= 19628;
case WindowTransparencyLevel.None:
accent.AccentState = AccentState.ACCENT_DISABLED;
break;
case WindowTransparencyLevel.Transparent: var accent = new AccentPolicy();
accent.AccentState = AccentState.ACCENT_ENABLE_TRANSPARENTGRADIENT; var accentStructSize = Marshal.SizeOf(accent);
break;
case WindowTransparencyLevel.Blur: if (transparencyLevel == WindowTransparencyLevel.AcrylicBlur && !canUseAcrylic)
accent.AccentState = AccentState.ACCENT_ENABLE_BLURBEHIND; {
break; transparencyLevel = WindowTransparencyLevel.Blur;
}
case WindowTransparencyLevel.AcrylicBlur: switch (transparencyLevel)
case (WindowTransparencyLevel.AcrylicBlur + 1): // hack-force acrylic. {
accent.AccentState = AccentState.ACCENT_ENABLE_ACRYLIC; default:
transparencyLevel = WindowTransparencyLevel.AcrylicBlur; case WindowTransparencyLevel.None:
break; 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.AccentFlags = 2;
accent.GradientColor = 0x01000000; accent.GradientColor = 0x01000000;
var accentPtr = Marshal.AllocHGlobal(accentStructSize); var accentPtr = Marshal.AllocHGlobal(accentStructSize);
Marshal.StructureToPtr(accent, accentPtr, false); Marshal.StructureToPtr(accent, accentPtr, false);
var data = new WindowCompositionAttributeData(); var data = new WindowCompositionAttributeData();
data.Attribute = WindowCompositionAttribute.WCA_ACCENT_POLICY; data.Attribute = WindowCompositionAttribute.WCA_ACCENT_POLICY;
data.SizeOfData = accentStructSize; data.SizeOfData = accentStructSize;
data.Data = accentPtr; 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 }; public IEnumerable<object> Surfaces => new object[] { Handle, _gl, _framebuffer };

Loading…
Cancel
Save