Skip to content
Open
152 changes: 152 additions & 0 deletions specs/SystemBackdropHost Spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
SystemBackdropHost
===

# Background

There are some System backdrop materials such as Mica, Acrylic etc that are available in
`Microsoft.UI.Xaml.Media.SystemBackdrop`. Today, its possible to host a system backdrop only at the window level and only for flyouts, not in a specific container / control level. This have been a major limitation on WinUI3 compared to WinUI2 in achieving the acrylic / mica effects.

`SystemBackdropHost` is a lightweight `FrameworkElement` that bridges between the XAML tree and the composition
infrastructure required by `SystemBackdrop`. It creates the required composition components to host the systembackdrop on a specific container, keeps the placement
visual sized to the arranged bounds, and applies the element's `CornerRadius` to the backdrop clip so rounded corners
appear as expected. This control abstracts lot of details for the composition layer and hence make it easy
for WinUI3 developers to implement the acrylic effect in the applications.

## Goals

* Provide an intuitive, XAML-friendly way to place a system backdrop anywhere inside application's visual tree.
* Handle connection, disconnection, and sizing so application only have to set a backdrop and position the element.
* Allow to round the hosted backdrop without writing custom composition code.

## Non-goals

* Supporting backdrop independently on all controls.
* Provide a content container; `SystemBackdropHost` is purely a visual effect surface and does not host child content.

# Conceptual pages (How To)

The guidance in the below examples can be followed by developers for adopting
`SystemBackdropHost`.

# API Pages

_(Each level-two section below maps to a docs.microsoft.com API page.)_

## SystemBackdropHost class

Use `SystemBackdropHost` to place a system-provided material anywhere within your XAML layout.

```csharp
public sealed class SystemBackdropHost : FrameworkElement
```

### Examples

You can place the host behind header content while keeping the rest of the page unchanged:

```xml
<Grid x:Name="AnimatedGrid" Height="100" Width="100">
<Grid.Resources>
<Storyboard x:Name="SizeAnimation" RepeatBehavior="Forever">
<DoubleAnimation Storyboard.TargetName="AnimatedGrid"
Storyboard.TargetProperty="Width"
From="100" To="200" Duration="0:0:2"
RepeatBehavior="Forever"
EnableDependentAnimation="True"
AutoReverse="True"/>
<DoubleAnimation Storyboard.TargetName="AnimatedGrid"
Storyboard.TargetProperty="Height"
From="100" To="200" Duration="0:0:2"
EnableDependentAnimation="True"
RepeatBehavior="Forever"
AutoReverse="True"/>
</Storyboard>
</Grid.Resources>
<SystemBackdropHost CornerRadius="4">
<SystemBackdropHost.SystemBackdrop>
<DesktopAcrylicBackdrop />
</SystemBackdropHost.SystemBackdrop>
</SystemBackdropHost>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find this approach as a content item to be weird, and it prevents creating styles with this backdrop. My preference would be a form of brush I can just set as a background brush. In the community call it was mentioned it was hard to do with the current infrastructure, but as an alternative I'd suggest doing this as an attached property instead of a content element. That would allow you to create styles that have the backdrop defined.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would also make adding Acrylic support for those controls that need it, breaking changes, that will require devs to re-template to insert this new object into the visual tree right?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we need to have an attached property on a Control for SystemBackdrop (I guess you mean similar to what we have on Window / Popup), we would need to have a placeholder container added in the control template beneath other parts of the control so that when the backdrop material is applied, the placementVisual can be added to the particular 'placeholder container'. This would affect the fundamentals especially for apps that have very big visual tree, We didn't want to do that on all control templates for supporting a feature that is not very likely to be applied on all instances of the control.

Copy link
Contributor

@dotMorten dotMorten Nov 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@godlytalias Are you saying that WinUI itself doesn't have access to the internal rendering engine to inject this at a lower level when needed? If you're saying it requires re-templating, then you're still thinking of this in terms of adding more FrameworkElements into the UI tree, rather than at the rendering tier level.
Not being able to create custom styles with this setting is a huge break from how we generally develop and designs UIs and easily update and reuse styling. I'd like to be able to do:

<Page.Resources>
  <Style TargetType="Grid" x:Key="AcrylicGrid">
    <Setter Property="SystemBackdrop.Backdrop">
       <Setter.Value>
            <DesktopAcrylicBackdrop /> 
       </Setter.Value>
    </Setter>
  </Style>
</Page.Resources>
<Grid Style="{StaticResource AcrylicGrid}">

</Grid>

The current proposal completely prevents this and feels like a quick band-aid solution.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, We wanted to avoid making lot of changes into the rendering stack of WinUI to support SystemBackdrop. We are looking at bringing the support to WinUI3 in the future more similar to the UWP way of using brush. So we came up with this quick and lightweight solution to bridge the gap and to ensure that critical scenarios are unblocked.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally agree with @dotMorten. Since the WinAppSdk v2.0 will introduce the breaking changes, I don't think this

avoid making lot of changes into the rendering stack of WinUI to support SystemBackdrop

is an issue, especially when you guys target this feature for v2.0.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dotMorten @d2phap Thanks for the responses, However the cost of introducing rendering stack changes to support backdrop is not trivial and don't fit into the 2.0 release timelines as well. Moreover as I mentioned above, we have the longterm plan related to compositor to make things work similar to the UWP case, Hence putting such a big cost into making changes to rendering stack is not a wise decision.
Considering the risks & cost of such a solution it was put out of scope for 2.0 release.
We're also evaluating the necessity of bringing this solution down-level to 1.* versions as well, based on the requirements of some critical scenarios.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discussion: Why it is not same as WinUI2, means use it as brush property? In proc lifted compositor puts restriction on its implementation.

Z-order is currently based on Xaml order. We could have helper for developers to place this control in right z-order. But covering all cases will be challenging. So, keeping the API simple and developer can place it correctly based on use case.

It will go as control. No change required.

<Button Content="Test Button"/>
</Grid>
```

![Example of SystemBackdropHost with animation](images/Acrylic.gif)

The same pattern works from code:

* C#:
```csharp
var host = new SystemBackdropHost
{
SystemBackdrop = new MicaBackdrop(),
CornerRadius = new CornerRadius(12)
};
rootGrid.Children.Add(host);
```

* C++:
```cpp
winrt::Microsoft::UI::Xaml::Controls::SystemBackdropHost host;
host.SystemBackdrop(winrt::Microsoft::UI::Xaml::Media::MicaBackdrop());
host.CornerRadius(winrt::CornerRadius{ 12, 12, 12, 12 });
rootGrid().Children().Append(host);
```

In both snippets, `rootGrid` represents the panel that hosts the backdrop surface just behind your content.

### Remarks

* _Spec note: This API is currently `experimental`; the API surface may still change before it is finalized._
* The element have to be placed as first element in the container (for example as the first child inside a
panel) for having the backdrop below the contents.
* The host only connects to a backdrop while it has a `XamlRoot`. If the element is not in the live tree, the backdrop
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should see if we can scrub other uses of "host" in the document. For example, here we talk about the host -- is this talking about the variable named host? Or some other host concept? If the variable named host then should say "The SystemBackdropElement only connects to a backdrop while it has a XamlRoot." Similarly "If the host is not yet loaded.." should be "If the SystemBackdropElement is not yet loaded..." etc.

Later, we say "Gets or sets the SystemBackdrop instance that renders in the host area." What is the "host area"?

remains disconnected until it is loaded again.

## SystemBackdropHost.SystemBackdrop property

Gets or sets the `SystemBackdrop` instance that renders in the host area. The default value is `null`.

* When you assign a non-null backdrop and the host is loaded, it calls `SystemBackdrop.OnTargetConnected` with a
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this stuff implementation detail, or does a developer need to know this to use the SystemBackdrop properly?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Recommend: Remove OnTargetConnected/Disconnected details as it works same as SystemBackDropHost.

`ContentExternalBackdropLink` that matches the element's arranged size. If the host is not yet loaded, the connection
happens the next time it loads.
* Changing the property disconnects the previous backdrop (through `OnTargetDisconnected`) before connecting the new
value. Setting the property to `null` releases the composition resources and removes the child visual from the
element.
* You can data bind or animate this property. Typical values include `MicaBackdrop`, `DesktopAcrylicBackdrop`, or a
custom subclass of `SystemBackdrop`.
* If the host does not yet have a `XamlRoot`, the connection is postponed until one becomes available.

## SystemBackdropHost.CornerRadius property

Gets or sets the `CornerRadius` applied to the hosted backdrop surface. The default value is `CornerRadius(0)`.

* The host applies a `RectangleClip` on the placement visual to achieve the rounded corners.
* Updating the property while the element is loaded immediately refreshes the clip. Setting the property to `null` (for
example through a binding) clears the stored corner radius and restores square corners.
* This property only affects the backdrop clip. It does not change layout or round other content layered above the
host.

# API Details

```csharp
namespace Microsoft.UI.Xaml.Controls
{
[MUX_PREVIEW]
[webhosthidden]
public sealed class SystemBackdropHost : Microsoft.UI.Xaml.FrameworkElement
{
public SystemBackdropHost();

public Microsoft.UI.Xaml.Media.SystemBackdrop SystemBackdrop { get; set; }
public static Microsoft.UI.Xaml.DependencyProperty SystemBackdropProperty { get; }

public Microsoft.UI.Xaml.CornerRadius CornerRadius { get; set; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discussion: Should it have CornerRadius or it should just clip based on parent? If parent and systembaclkdrophost has different corner radius, corner area becomes interesting.

Image inside border is analogy.

Recommend: Call out interesting corner clipping cases

public static Microsoft.UI.Xaml.DependencyProperty CornerRadiusProperty { get; }
}
}
```

# Appendix

Additional property for `SystemBackdropHost` to hold a child content can be considered at a later point based on requirement.
Binary file added specs/images/Acrylic.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading