diff --git a/samples/ControlCatalog/MainView.xaml b/samples/ControlCatalog/MainView.xaml
index 6537c470d5..f61b59e6cd 100644
--- a/samples/ControlCatalog/MainView.xaml
+++ b/samples/ControlCatalog/MainView.xaml
@@ -98,6 +98,7 @@
Transparent
Blur
AcrylicBlur
+ Mica
diff --git a/samples/ControlCatalog/MainWindow.xaml b/samples/ControlCatalog/MainWindow.xaml
index a107ee2163..ee42e7a54b 100644
--- a/samples/ControlCatalog/MainWindow.xaml
+++ b/samples/ControlCatalog/MainWindow.xaml
@@ -12,6 +12,7 @@
ExtendClientAreaTitleBarHeightHint="{Binding TitleBarHeight}"
TransparencyLevelHint="{Binding TransparencyLevel}"
x:Name="MainWindow"
+ Background="Transparent"
x:Class="ControlCatalog.MainWindow" WindowState="{Binding WindowState, Mode=TwoWay}">
diff --git a/samples/ControlCatalog/Pages/WindowCustomizationsPage.xaml b/samples/ControlCatalog/Pages/WindowCustomizationsPage.xaml
index b90f43c3b6..caab42e98c 100644
--- a/samples/ControlCatalog/Pages/WindowCustomizationsPage.xaml
+++ b/samples/ControlCatalog/Pages/WindowCustomizationsPage.xaml
@@ -14,6 +14,7 @@
Transparent
Blur
AcrylicBlur
+ Mica
diff --git a/src/Avalonia.Controls.DataGrid/DataGridColumn.cs b/src/Avalonia.Controls.DataGrid/DataGridColumn.cs
index 4ab2869138..5499257171 100644
--- a/src/Avalonia.Controls.DataGrid/DataGridColumn.cs
+++ b/src/Avalonia.Controls.DataGrid/DataGridColumn.cs
@@ -9,6 +9,7 @@ using Avalonia.VisualTree;
using Avalonia.Collections;
using Avalonia.Utilities;
using System;
+using System.ComponentModel;
using System.Linq;
using System.Diagnostics;
using Avalonia.Controls.Utils;
@@ -653,6 +654,34 @@ namespace Avalonia.Controls
return null;
}
+ ///
+ /// Clears the current sort direction
+ ///
+ public void ClearSort()
+ {
+ //InvokeProcessSort is already validating if sorting is possible
+ _headerCell?.InvokeProcessSort(Input.KeyModifiers.Control);
+ }
+
+ ///
+ /// Switches the current state of sort direction
+ ///
+ public void Sort()
+ {
+ //InvokeProcessSort is already validating if sorting is possible
+ _headerCell?.InvokeProcessSort(Input.KeyModifiers.None);
+ }
+
+ ///
+ /// Changes the sort direction of this column
+ ///
+ /// New sort direction
+ public void Sort(ListSortDirection direction)
+ {
+ //InvokeProcessSort is already validating if sorting is possible
+ _headerCell?.InvokeProcessSort(Input.KeyModifiers.None, direction);
+ }
+
///
/// When overridden in a derived class, causes the column cell being edited to revert to the unedited value.
///
diff --git a/src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs b/src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs
index 6f957497cb..85fd55800a 100644
--- a/src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs
+++ b/src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs
@@ -201,21 +201,21 @@ namespace Avalonia.Controls
handled = true;
}
- internal void InvokeProcessSort(KeyModifiers keyModifiers)
+ internal void InvokeProcessSort(KeyModifiers keyModifiers, ListSortDirection? forcedDirection = null)
{
Debug.Assert(OwningGrid != null);
- if (OwningGrid.WaitForLostFocus(() => InvokeProcessSort(keyModifiers)))
+ if (OwningGrid.WaitForLostFocus(() => InvokeProcessSort(keyModifiers, forcedDirection)))
{
return;
}
if (OwningGrid.CommitEdit(DataGridEditingUnit.Row, exitEditingMode: true))
{
- Avalonia.Threading.Dispatcher.UIThread.Post(() => ProcessSort(keyModifiers));
+ Avalonia.Threading.Dispatcher.UIThread.Post(() => ProcessSort(keyModifiers, forcedDirection));
}
}
//TODO GroupSorting
- internal void ProcessSort(KeyModifiers keyModifiers)
+ internal void ProcessSort(KeyModifiers keyModifiers, ListSortDirection? forcedDirection = null)
{
// if we can sort:
// - AllowUserToSortColumns and CanSort are true, and
@@ -259,7 +259,14 @@ namespace Avalonia.Controls
{
if (sort != null)
{
- newSort = sort.SwitchSortDirection();
+ if (forcedDirection == null || sort.Direction != forcedDirection)
+ {
+ newSort = sort.SwitchSortDirection();
+ }
+ else
+ {
+ newSort = sort;
+ }
// changing direction should not affect sort order, so we replace this column's
// sort description instead of just adding it to the end of the collection
@@ -276,7 +283,10 @@ namespace Avalonia.Controls
}
else if (OwningColumn.CustomSortComparer != null)
{
- newSort = DataGridSortDescription.FromComparer(OwningColumn.CustomSortComparer);
+ newSort = forcedDirection != null ?
+ DataGridSortDescription.FromComparer(OwningColumn.CustomSortComparer, forcedDirection.Value) :
+ DataGridSortDescription.FromComparer(OwningColumn.CustomSortComparer);
+
owningGrid.DataConnection.SortDescriptions.Add(newSort);
}
@@ -290,6 +300,10 @@ namespace Avalonia.Controls
}
newSort = DataGridSortDescription.FromPath(propertyName, culture: collectionView.Culture);
+ if (forcedDirection != null && newSort.Direction != forcedDirection)
+ {
+ newSort = newSort.SwitchSortDirection();
+ }
owningGrid.DataConnection.SortDescriptions.Add(newSort);
}
diff --git a/src/Avalonia.Controls/Repeater/ItemsRepeater.cs b/src/Avalonia.Controls/Repeater/ItemsRepeater.cs
index 01200e87e3..0ff8fcbd28 100644
--- a/src/Avalonia.Controls/Repeater/ItemsRepeater.cs
+++ b/src/Avalonia.Controls/Repeater/ItemsRepeater.cs
@@ -588,14 +588,14 @@ namespace Avalonia.Controls
throw new AvaloniaInternalException("Cannot set ItemsSourceView during layout.");
}
- ItemsSourceView?.Dispose();
- ItemsSourceView = newValue;
-
if (oldValue != null)
{
oldValue.CollectionChanged -= OnItemsSourceViewChanged;
}
+ ItemsSourceView?.Dispose();
+ ItemsSourceView = newValue;
+
if (newValue != null)
{
newValue.CollectionChanged += OnItemsSourceViewChanged;
diff --git a/src/Avalonia.Controls/WindowTransparencyLevel.cs b/src/Avalonia.Controls/WindowTransparencyLevel.cs
index ce7c03efbb..f416b5de91 100644
--- a/src/Avalonia.Controls/WindowTransparencyLevel.cs
+++ b/src/Avalonia.Controls/WindowTransparencyLevel.cs
@@ -20,6 +20,11 @@
///
/// The window background is a blur-behind with a high blur radius. This level may fallback to Blur.
///
- AcrylicBlur
+ AcrylicBlur,
+
+ ///
+ /// The window background is based on desktop wallpaper tint with a blur. This will only work on Windows 11
+ ///
+ Mica
}
}
diff --git a/src/Avalonia.Visuals/Media/DrawingImage.cs b/src/Avalonia.Visuals/Media/DrawingImage.cs
index 56c883014a..6fa8d397a5 100644
--- a/src/Avalonia.Visuals/Media/DrawingImage.cs
+++ b/src/Avalonia.Visuals/Media/DrawingImage.cs
@@ -11,6 +11,14 @@ namespace Avalonia.Media
///
public class DrawingImage : AvaloniaObject, IImage, IAffectsRender
{
+ public DrawingImage()
+ {
+ }
+
+ public DrawingImage(Drawing drawing)
+ {
+ Drawing = drawing;
+ }
///
/// Defines the property.
///
diff --git a/src/Avalonia.X11/X11Platform.cs b/src/Avalonia.X11/X11Platform.cs
index 5d80c860a7..d3aeefd088 100644
--- a/src/Avalonia.X11/X11Platform.cs
+++ b/src/Avalonia.X11/X11Platform.cs
@@ -52,11 +52,14 @@ namespace Avalonia.X11
XInitThreads();
Display = XOpenDisplay(IntPtr.Zero);
+ if (Display == IntPtr.Zero)
+ throw new Exception("XOpenDisplay failed");
DeferredDisplay = XOpenDisplay(IntPtr.Zero);
+ if (DeferredDisplay == IntPtr.Zero)
+ throw new Exception("XOpenDisplay failed");
+
OrphanedWindow = XCreateSimpleWindow(Display, XDefaultRootWindow(Display), 0, 0, 1, 1, 0, IntPtr.Zero,
IntPtr.Zero);
- if (Display == IntPtr.Zero)
- throw new Exception("XOpenDisplay failed");
XError.Init();
Info = new X11Info(Display, DeferredDisplay, useXim);
diff --git a/src/Windows/Avalonia.Win32/Win32GlManager.cs b/src/Windows/Avalonia.Win32/Win32GlManager.cs
index e70ea52106..289c100d51 100644
--- a/src/Windows/Avalonia.Win32/Win32GlManager.cs
+++ b/src/Windows/Avalonia.Win32/Win32GlManager.cs
@@ -27,7 +27,7 @@ namespace Avalonia.Win32
if (egl != null &&
opts?.UseWindowsUIComposition == true)
{
- WinUICompositorConnection.TryCreateAndRegister(egl);
+ WinUICompositorConnection.TryCreateAndRegister(egl, opts.CompositionBackdropCornerRadius);
}
return egl;
diff --git a/src/Windows/Avalonia.Win32/Win32Platform.cs b/src/Windows/Avalonia.Win32/Win32Platform.cs
index 45fa8f44ce..2947493c41 100644
--- a/src/Windows/Avalonia.Win32/Win32Platform.cs
+++ b/src/Windows/Avalonia.Win32/Win32Platform.cs
@@ -89,6 +89,13 @@ namespace Avalonia
/// This is recommended if you need to use AcrylicBlur or acrylic in your applications.
///
public bool UseWindowsUIComposition { get; set; } = true;
+
+ ///
+ /// When enabled, create rounded corner blur brushes
+ /// If set to null the brushes will be created using default settings (sharp corners)
+ /// This can be useful when you need a rounded-corner blurred Windows 10 app, or borderless Windows 11 app
+ ///
+ public float? CompositionBackdropCornerRadius { get; set; }
}
}
diff --git a/src/Windows/Avalonia.Win32/WinRT/Composition/WinUICompositedWindow.cs b/src/Windows/Avalonia.Win32/WinRT/Composition/WinUICompositedWindow.cs
index 4ae9c08410..a09918a3a6 100644
--- a/src/Windows/Avalonia.Win32/WinRT/Composition/WinUICompositedWindow.cs
+++ b/src/Windows/Avalonia.Win32/WinRT/Composition/WinUICompositedWindow.cs
@@ -13,6 +13,8 @@ namespace Avalonia.Win32.WinRT.Composition
{
private EglContext _syncContext;
private readonly object _pumpLock;
+ private readonly IVisual _micaVisual;
+ private readonly ICompositionRoundedRectangleGeometry _roundedRectangleGeometry;
private readonly IVisual _blurVisual;
private ICompositionTarget _compositionTarget;
private IVisual _contentVisual;
@@ -28,11 +30,14 @@ namespace Avalonia.Win32.WinRT.Composition
object pumpLock,
ICompositionTarget compositionTarget,
ICompositionDrawingSurfaceInterop surfaceInterop,
- IVisual contentVisual, IVisual blurVisual)
+ IVisual contentVisual, IVisual blurVisual, IVisual micaVisual,
+ ICompositionRoundedRectangleGeometry roundedRectangleGeometry)
{
_compositor = compositor.CloneReference();
_syncContext = syncContext;
_pumpLock = pumpLock;
+ _micaVisual = micaVisual;
+ _roundedRectangleGeometry = roundedRectangleGeometry;
_blurVisual = blurVisual.CloneReference();
_compositionTarget = compositionTarget.CloneReference();
_contentVisual = contentVisual.CloneReference();
@@ -48,6 +53,7 @@ namespace Avalonia.Win32.WinRT.Composition
{
_surfaceInterop.Resize(new UnmanagedMethods.POINT { X = size.Width, Y = size.Height });
_contentVisual.SetSize(new Vector2(size.Width, size.Height));
+ _roundedRectangleGeometry?.SetSize(new Vector2(size.Width, size.Height));
_size = size;
}
}
@@ -72,10 +78,13 @@ namespace Avalonia.Win32.WinRT.Composition
_surfaceInterop.EndDraw();
}
- public void SetBlur(bool enable)
+ public void SetBlur(BlurEffect blurEffect)
{
using (_syncContext.EnsureLocked())
- _blurVisual.SetIsVisible(enable ? 1 : 0);
+ {
+ _blurVisual.SetIsVisible(blurEffect == BlurEffect.Acrylic ? 1 : 0);
+ _micaVisual?.SetIsVisible(blurEffect == BlurEffect.Mica ? 1 : 0);
+ }
}
public IDisposable BeginTransaction()
diff --git a/src/Windows/Avalonia.Win32/WinRT/Composition/WinUICompositorConnection.cs b/src/Windows/Avalonia.Win32/WinRT/Composition/WinUICompositorConnection.cs
index bc8f5a606c..57b0f71306 100644
--- a/src/Windows/Avalonia.Win32/WinRT/Composition/WinUICompositorConnection.cs
+++ b/src/Windows/Avalonia.Win32/WinRT/Composition/WinUICompositorConnection.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.Diagnostics;
using System.Numerics;
using System.Runtime.InteropServices;
@@ -16,7 +17,9 @@ namespace Avalonia.Win32.WinRT.Composition
{
class WinUICompositorConnection : IRenderTimer
{
+ private readonly float? _backdropCornerRadius;
private readonly EglContext _syncContext;
+ private readonly ICompositionBrush _micaBrush;
private ICompositor _compositor;
private ICompositor2 _compositor2;
private ICompositor5 _compositor5;
@@ -28,10 +31,11 @@ namespace Avalonia.Win32.WinRT.Composition
private ICompositionBrush _blurBrush;
private object _pumpLock = new object();
- public WinUICompositorConnection(EglPlatformOpenGlInterface gl, object pumpLock)
+ public WinUICompositorConnection(EglPlatformOpenGlInterface gl, object pumpLock, float? backdropCornerRadius)
{
_gl = gl;
_pumpLock = pumpLock;
+ _backdropCornerRadius = backdropCornerRadius;
_syncContext = _gl.PrimaryEglContext;
_angle = (AngleWin32EglDisplay)_gl.Display;
_compositor = NativeWinRTMethods.CreateInstance("Windows.UI.Composition.Compositor");
@@ -42,13 +46,13 @@ namespace Avalonia.Win32.WinRT.Composition
using var device = MicroComRuntime.CreateProxyFor(_angle.GetDirect3DDevice(), true);
_device = _compositorInterop.CreateGraphicsDevice(device);
- _blurBrush = CreateBlurBrush();
-
+ _blurBrush = CreateAcrylicBlurBackdropBrush();
+ _micaBrush = CreateMicaBackdropBrush();
}
public EglPlatformOpenGlInterface Egl => _gl;
- static bool TryCreateAndRegisterCore(EglPlatformOpenGlInterface angle)
+ static bool TryCreateAndRegisterCore(EglPlatformOpenGlInterface angle, float? backdropCornerRadius)
{
var tcs = new TaskCompletionSource();
var pumpLock = new object();
@@ -63,7 +67,7 @@ namespace Avalonia.Win32.WinRT.Composition
dwSize = Marshal.SizeOf(),
threadType = NativeWinRTMethods.DISPATCHERQUEUE_THREAD_TYPE.DQTYPE_THREAD_CURRENT
});
- connect = new WinUICompositorConnection(angle, pumpLock);
+ connect = new WinUICompositorConnection(angle, pumpLock, backdropCornerRadius);
AvaloniaLocator.CurrentMutable.BindToSelf(connect);
AvaloniaLocator.CurrentMutable.Bind().ToConstant(connect);
tcs.SetResult(true);
@@ -130,7 +134,8 @@ namespace Avalonia.Win32.WinRT.Composition
}
}
- public static void TryCreateAndRegister(EglPlatformOpenGlInterface angle)
+ public static void TryCreateAndRegister(EglPlatformOpenGlInterface angle,
+ float? backdropCornerRadius)
{
const int majorRequired = 10;
const int buildRequired = 17134;
@@ -143,7 +148,7 @@ namespace Avalonia.Win32.WinRT.Composition
{
try
{
- TryCreateAndRegisterCore(angle);
+ TryCreateAndRegisterCore(angle, backdropCornerRadius);
return;
}
catch (Exception e)
@@ -188,16 +193,37 @@ namespace Avalonia.Win32.WinRT.Composition
target.SetRoot(containerVisual);
- using var blur = CreateBlurVisual();
+ using var blur = CreateBlurVisual(_blurBrush);
+ IVisual mica = null;
+ if (_micaBrush != null)
+ {
+ mica = CreateBlurVisual(_micaBrush);
+ containerChildren.InsertAtTop(mica);
+ }
+
+ var compositionRoundedRectangleGeometry = ClipVisual(blur, mica);
containerChildren.InsertAtTop(blur);
containerChildren.InsertAtTop(visual);
- return new WinUICompositedWindow(_syncContext, _compositor, _pumpLock, target, surfaceInterop, visual, blur);
+ return new WinUICompositedWindow(_syncContext, _compositor, _pumpLock, target, surfaceInterop, visual,
+ blur, mica, compositionRoundedRectangleGeometry);
}
+ private ICompositionBrush CreateMicaBackdropBrush()
+ {
+ if (Win32Platform.WindowsVersion.Build < 22000)
+ return null;
+
+ using var compositorWithBlurredWallpaperBackdropBrush =
+ _compositor.QueryInterface();
+ using var blurredWallpaperBackdropBrush =
+ compositorWithBlurredWallpaperBackdropBrush?.TryCreateBlurredWallpaperBackdropBrush();
+ using var micaBackdropBrush = blurredWallpaperBackdropBrush?.QueryInterface();
+ return micaBackdropBrush.CloneReference();
+ }
- private unsafe ICompositionBrush CreateBlurBrush()
+ private unsafe ICompositionBrush CreateAcrylicBlurBackdropBrush()
{
using var backDropParameterFactory = NativeWinRTMethods.CreateActivationFactory(
"Windows.UI.Composition.CompositionEffectSourceParameter");
@@ -207,6 +233,7 @@ namespace Avalonia.Win32.WinRT.Composition
using var backDropParameterAsSource = backDropParameter.QueryInterface();
var blurEffect = new WinUIGaussianBlurEffect(backDropParameterAsSource);
using var blurEffectFactory = _compositor.CreateEffectFactory(blurEffect);
+ using var compositionEffectBrush = blurEffectFactory.CreateBrush();
using var backdrop = _compositor2.CreateBackdropBrush();
using var backdropBrush = backdrop.QueryInterface();
@@ -214,18 +241,39 @@ namespace Avalonia.Win32.WinRT.Composition
var saturateEffect = new SaturationEffect(blurEffect);
using var satEffectFactory = _compositor.CreateEffectFactory(saturateEffect);
using var sat = satEffectFactory.CreateBrush();
- sat.SetSourceParameter(backdropString.Handle, backdropBrush);
- return sat.QueryInterface();
+ compositionEffectBrush.SetSourceParameter(backdropString.Handle, backdropBrush);
+ return compositionEffectBrush.QueryInterface();
+ }
+
+ private ICompositionRoundedRectangleGeometry ClipVisual(params IVisual[] containerVisuals)
+ {
+ if (!_backdropCornerRadius.HasValue)
+ return null;
+ using var roundedRectangleGeometry = _compositor5.CreateRoundedRectangleGeometry();
+ roundedRectangleGeometry.SetCornerRadius(new Vector2(_backdropCornerRadius.Value, _backdropCornerRadius.Value));
+
+ using var compositor6 = _compositor.QueryInterface();
+ using var compositionGeometry = roundedRectangleGeometry
+ .QueryInterface();
+
+ using var geometricClipWithGeometry =
+ compositor6.CreateGeometricClipWithGeometry(compositionGeometry);
+ foreach (var visual in containerVisuals)
+ {
+ visual?.SetClip(geometricClipWithGeometry.QueryInterface());
}
- private unsafe IVisual CreateBlurVisual()
+ return roundedRectangleGeometry.CloneReference();
+ }
+
+ private unsafe IVisual CreateBlurVisual(ICompositionBrush compositionBrush)
{
using var spriteVisual = _compositor.CreateSpriteVisual();
using var visual = spriteVisual.QueryInterface();
using var visual2 = spriteVisual.QueryInterface();
- spriteVisual.SetBrush(_blurBrush);
+ spriteVisual.SetBrush(compositionBrush);
visual.SetIsVisible(0);
visual2.SetRelativeSizeAdjustment(new Vector2(1.0f, 1.0f));
diff --git a/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositedWindowSurface.cs b/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositedWindowSurface.cs
index f59d50860a..4ed882552b 100644
--- a/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositedWindowSurface.cs
+++ b/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositedWindowSurface.cs
@@ -15,7 +15,7 @@ namespace Avalonia.Win32.WinRT.Composition
private EglPlatformOpenGlInterface _egl;
private readonly EglGlPlatformSurfaceBase.IEglWindowGlPlatformSurfaceInfo _info;
private IRef _window;
- private bool _enableBlur;
+ private BlurEffect _blurEffect;
public WinUiCompositedWindowSurface(WinUICompositorConnection connection, IEglWindowGlPlatformSurfaceInfo info) : base()
{
@@ -31,7 +31,7 @@ namespace Avalonia.Win32.WinRT.Composition
if (_window?.Item == null)
{
_window = RefCountable.Create(_connection.CreateWindow(_info.Handle));
- _window.Item.SetBlur(_enableBlur);
+ _window.Item.SetBlur(_blurEffect);
}
return new CompositionRenderTarget(_egl, _window, _info);
@@ -100,10 +100,10 @@ namespace Avalonia.Win32.WinRT.Composition
}
}
- public void SetBlur(bool enable)
+ public void SetBlur(BlurEffect blurEffect)
{
- _enableBlur = enable;
- _window?.Item?.SetBlur(enable);
+ _blurEffect = blurEffect;
+ _window?.Item?.SetBlur(blurEffect);
}
public void Dispose()
diff --git a/src/Windows/Avalonia.Win32/WinRT/IBlurHost.cs b/src/Windows/Avalonia.Win32/WinRT/IBlurHost.cs
index 81c0e3e185..526be6e0f0 100644
--- a/src/Windows/Avalonia.Win32/WinRT/IBlurHost.cs
+++ b/src/Windows/Avalonia.Win32/WinRT/IBlurHost.cs
@@ -1,7 +1,14 @@
namespace Avalonia.Win32.WinRT
{
- public interface IBlurHost
+ public enum BlurEffect
{
- void SetBlur(bool enable);
+ None,
+ Acrylic,
+ Mica
+ }
+
+ internal interface IBlurHost
+ {
+ void SetBlur(BlurEffect enable);
}
}
diff --git a/src/Windows/Avalonia.Win32/WinRT/winrt.idl b/src/Windows/Avalonia.Win32/WinRT/winrt.idl
index 929377999c..18a9a26fca 100644
--- a/src/Windows/Avalonia.Win32/WinRT/winrt.idl
+++ b/src/Windows/Avalonia.Win32/WinRT/winrt.idl
@@ -358,6 +358,12 @@ interface ICompositor2 : IInspectable
[overload("CreateStepEasingFunction")] HRESULT CreateStepEasingFunctionWithStepCount([in] INT32 stepCount, [out] [retval] void** result);
}
+[uuid(0D8FB190-F122-5B8D-9FDD-543B0D8EB7F3)]
+interface ICompositorWithBlurredWallpaperBackdropBrush : IInspectable
+{
+ HRESULT TryCreateBlurredWallpaperBackdropBrush([out] [retval] ICompositionBackdropBrush** result);
+}
+
[uuid(08E05581-1AD1-4F97-9757-402D76E4233B)]
interface ISpriteVisual : IInspectable
{
@@ -520,6 +526,13 @@ enum CompositionCompositeMode
MinBlend,
}
+[contract(Windows.Foundation.UniversalApiContract, 2.0)]
+[exclusiveto(Windows.UI.Composition.CompositionClip)]
+[uuid(1CCD2A52-CFC7-4ACE-9983-146BB8EB6A3C)]
+interface ICompositionClip : IInspectable
+{
+}
+
[uuid(117E202D-A859-4C89-873B-C2AA566788E3)]
interface IVisual : IInspectable
{
@@ -531,8 +544,8 @@ interface IVisual : IInspectable
[propput] HRESULT BorderMode([in] CompositionBorderMode value);
[propget] HRESULT CenterPoint([out] [retval] Vector3* value);
[propput] HRESULT CenterPoint([in] Vector3 value);
- [propget] HRESULT Clip([out] [retval]void** value);
- [propput] HRESULT Clip([in] void* value);
+ [propget] HRESULT Clip([out] [retval] ICompositionClip** value);
+ [propput] HRESULT Clip([in] ICompositionClip* value);
[propget] HRESULT CompositeMode([out] [retval] CompositionCompositeMode* value);
[propput] HRESULT CompositeMode([in] CompositionCompositeMode value);
[propget] HRESULT IsVisible([out] [retval] boolean* value);
@@ -692,6 +705,99 @@ interface ICompositionScopedBatch : IInspectable
[eventremove] HRESULT RemoveCompleted([in] int token);
}
+[contract(Windows.Foundation.UniversalApiContract, 6.0)]
+[exclusiveto(Windows.UI.Composition.CompositionRoundedRectangleGeometry)]
+[uuid(8770C822-1D50-4B8B-B013-7C9A0E46935F)]
+interface ICompositionRoundedRectangleGeometry : IInspectable
+{
+ [propget] HRESULT CornerRadius([out] [retval] Vector2* value);
+ [propput] HRESULT CornerRadius([in] Vector2 value);
+ [propget] HRESULT Offset([out] [retval] Vector2* value);
+ [propput] HRESULT Offset([in] Vector2 value);
+ [propget] HRESULT Size([out] [retval] Vector2* value);
+ [propput] HRESULT Size([in] Vector2 value);
+}
+
+[contract(Windows.Foundation.UniversalApiContract, 6.0)]
+[exclusiveto(Windows.UI.Composition.CompositionGeometry)]
+[uuid(E985217C-6A17-4207-ABD8-5FD3DD612A9D)]
+interface ICompositionGeometry : IInspectable
+{
+ [propget] HRESULT TrimEnd([out] [retval] FLOAT* value);
+ [propput] HRESULT TrimEnd([in] FLOAT value);
+ [propget] HRESULT TrimOffset([out] [retval] FLOAT* value);
+ [propput] HRESULT TrimOffset([in] FLOAT value);
+ [propget] HRESULT TrimStart([out] [retval] FLOAT* value);
+ [propput] HRESULT TrimStart([in] FLOAT value);
+}
+
+[uuid(401B61BB-0007-4363-B1F3-6BCC003FB83E)]
+interface ICompositionSpriteShape : IInspectable
+{
+ [propget] HRESULT GetFillBrush([out] [retval] ICompositionBrush** value);
+ [propput] HRESULT SetFillBrush([in] ICompositionBrush* value);
+ [propget] HRESULT Geometry([out] [retval] ICompositionGeometry** value);
+ [propput] HRESULT Geometry([in] ICompositionGeometry* value);
+ [propget] HRESULT IsStrokeNonScaling([out] [retval] boolean* value);
+ [propput] HRESULT IsStrokeNonScaling([in] boolean value);
+ [propget] HRESULT StrokeBrush([out] [retval] ICompositionBrush** value);
+ [propput] HRESULT StrokeBrush([in] ICompositionBrush* value);
+ [propget] HRESULT StrokeDashArray();
+ [propget] HRESULT StrokeDashCap();
+ [propput] HRESULT StrokeDashCap();
+ [propget] HRESULT StrokeDashOffset();
+ [propput] HRESULT StrokeDashOffset();
+ [propget] HRESULT StrokeEndCap();
+ [propput] HRESULT StrokeEndCap();
+ [propget] HRESULT StrokeLineJoin();
+ [propput] HRESULT StrokeLineJoin();
+ [propget] HRESULT StrokeMiterLimit();
+ [propput] HRESULT StrokeMiterLimit();
+ [propget] HRESULT StrokeStartCap();
+ [propput] HRESULT StrokeStartCap();
+ [propget] HRESULT StrokeThickness();
+ [propput] HRESULT StrokeThickness();
+}
+
+[contract(Windows.Foundation.UniversalApiContract, 6.0)]
+[exclusiveto(Windows.UI.Composition.CompositionShape)]
+[uuid(B47CE2F7-9A88-42C4-9E87-2E500CA8688C)]
+interface ICompositionShape : IInspectable
+{
+ [propget] HRESULT CenterPoint([out] [retval] Vector2* value);
+ [propput] HRESULT CenterPoint([in] Vector2 value);
+}
+
+[uuid(42d4219a-be1b-5091-8f1e-90270840fc2d)]
+interface IVectorOfCompositionShape : IInspectable
+{
+ HRESULT GetAt();
+ [propget] HRESULT GetSize();
+ HRESULT GetView();
+ HRESULT IndexOf();
+ HRESULT SetAt();
+ HRESULT InsertAt();
+ HRESULT RemoveAt();
+ HRESULT Append([in] ICompositionShape* value);
+ HRESULT RemoveAtEnd();
+ HRESULT Clear();
+}
+
+[contract(Windows.Foundation.UniversalApiContract, 7.0)]
+[exclusiveto(Windows.UI.Composition.CompositionGeometricClip)]
+[uuid(C840B581-81C9-4444-A2C1-CCAECE3A50E5)]
+interface ICompositionGeometricClip : IInspectable
+{
+ [propget] HRESULT Geometry([out] [retval] ICompositionGeometry** value);
+ [propput] HRESULT Geometry([in] ICompositionGeometry* value);
+}
+
+[uuid(F2BD13C3-BA7E-4B0F-9126-FFB7536B8176)]
+interface IShapeVisual : IInspectable
+{
+ [propget] HRESULT Shapes([out] [retval] IUnknown** value);
+}
+
[uuid(48EA31AD-7FCD-4076-A79C-90CC4B852C9B)]
interface ICompositor5 : IInspectable
{
@@ -709,10 +815,19 @@ interface ICompositor5 : IInspectable
[overload("CreatePathGeometry")] HRESULT CreatePathGeometryWithPath([in] void* path, [out] [retval] void** result);
HRESULT CreatePathKeyFrameAnimation([out] [retval] void** result);
HRESULT CreateRectangleGeometry([out] [retval] void** result);
- HRESULT CreateRoundedRectangleGeometry([out] [retval] void** result);
- HRESULT CreateShapeVisual([out] [retval] void** result);
+ HRESULT CreateRoundedRectangleGeometry([out] [retval] ICompositionRoundedRectangleGeometry** result);
+ HRESULT CreateShapeVisual([out] [retval] IShapeVisual** result);
[overload("CreateSpriteShape")] HRESULT CreateSpriteShape([out] [retval] void** result);
[overload("CreateSpriteShape")] HRESULT CreateSpriteShapeWithGeometry([in] void* geometry, [out] [retval] void** result);
HRESULT CreateViewBox([out] [retval] void** result);
HRESULT RequestCommitAsync([out] [retval] IAsyncAction** operation);
}
+
+[contract(Windows.Foundation.UniversalApiContract, 7.0)]
+[exclusiveto(Windows.UI.Composition.Compositor)]
+[uuid(7A38B2BD-CEC8-4EEB-830F-D8D07AEDEBC3)]
+interface ICompositor6 : IInspectable
+{
+ [overload("CreateGeometricClip")] HRESULT CreateGeometricClip([out] [retval] ICompositionGeometricClip** result);
+ [overload("CreateGeometricClip")] HRESULT CreateGeometricClipWithGeometry([in] ICompositionGeometry* geometry, [out] [retval] ICompositionGeometricClip** result);
+}
diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs
index d1b2115cf6..b7fc35db72 100644
--- a/src/Windows/Avalonia.Win32/WindowImpl.cs
+++ b/src/Windows/Avalonia.Win32/WindowImpl.cs
@@ -373,7 +373,13 @@ namespace Avalonia.Win32
{
if (_isUsingComposition)
{
- _blurHost?.SetBlur(transparencyLevel >= WindowTransparencyLevel.Blur);
+ _blurHost?.SetBlur(transparencyLevel switch
+ {
+ WindowTransparencyLevel.Mica => BlurEffect.Mica,
+ WindowTransparencyLevel.AcrylicBlur => BlurEffect.Acrylic,
+ WindowTransparencyLevel.Blur => BlurEffect.Acrylic,
+ _ => BlurEffect.None
+ });
return transparencyLevel;
}
diff --git a/tests/Avalonia.Controls.UnitTests/ItemsRepeaterTests.cs b/tests/Avalonia.Controls.UnitTests/ItemsRepeaterTests.cs
new file mode 100644
index 0000000000..321676abc0
--- /dev/null
+++ b/tests/Avalonia.Controls.UnitTests/ItemsRepeaterTests.cs
@@ -0,0 +1,24 @@
+using System.Collections.ObjectModel;
+using Xunit;
+
+namespace Avalonia.Controls.UnitTests
+{
+ public class ItemsRepeaterTests
+ {
+ [Fact]
+ public void Can_Reassign_Items()
+ {
+ var target = new ItemsRepeater();
+ target.Items = new ObservableCollection();
+ target.Items = new ObservableCollection();
+ }
+
+ [Fact]
+ public void Can_Reassign_Items_To_Null()
+ {
+ var target = new ItemsRepeater();
+ target.Items = new ObservableCollection();
+ target.Items = null;
+ }
+ }
+}