Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved SystemBackdrop sample #1698

Merged
merged 23 commits into from
Jan 28, 2025
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions WinUIGallery/ContentIncludes.props
Original file line number Diff line number Diff line change
Expand Up @@ -245,10 +245,10 @@
<Content Include="ControlPagesSampleCode\System\FilePickerSample5_cs.txt" />
<Content Include="ControlPagesSampleCode\System\FilePickerSample5_xaml.txt" />
<Content Include="ControlPagesSampleCode\System\Window.txt" />
<Content Include="ControlPagesSampleCode\SystemBackdrops\SystemBackdropsSample1.txt" />
<Content Include="ControlPagesSampleCode\SystemBackdrops\SystemBackdropsSample1_cs.txt" />
<Content Include="ControlPagesSampleCode\SystemBackdrops\SystemBackdropsSample1_xaml.txt" />
<Content Include="ControlPagesSampleCode\SystemBackdrops\SystemBackdropsSample2.txt" />
<Content Include="ControlPagesSampleCode\SystemBackdrops\SystemBackdropsSample3.txt" />
niels9001 marked this conversation as resolved.
Show resolved Hide resolved
<Content Include="ControlPagesSampleCode\SystemBackdrops\SystemBackdropsSample4.txt" />
<Content Include="ControlPagesSampleCode\SystemBackdrops\SystemBackdropsEnsureSystemDQC.txt" />
<Content Include="ControlPagesSampleCode\TabView\TabViewBasicSample_cs.txt" />
<Content Include="ControlPagesSampleCode\TabView\TabViewKeyboardAcceleratorSample_cs.txt" />
Expand Down
73 changes: 41 additions & 32 deletions WinUIGallery/ControlPages/SystemBackdropsPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,45 +19,54 @@
mc:Ignorable="d">

<StackPanel>
<local:ControlExample HeaderText="Create a window with a built-in Mica system backdrop."
CSharpSource="SystemBackdrops\SystemBackdropsSample3.txt">
<local:ControlExample.Xaml>
<x:String xml:space="preserve">
// Option 1 - implement Mica with Xaml.
&lt;Window.SystemBackdrop&gt;
&lt;MicaBackdrop /&gt;
&lt;/Window.SystemBackdrop&gt;
</x:String>
</local:ControlExample.Xaml>
<Button Click="createBuiltInMicaWindow_Click">Create Window with built-in Mica</Button>
</local:ControlExample>

<local:ControlExample HeaderText="Create a window with a customizable Mica system backdrop."
CSharpSource="SystemBackdrops\SystemBackdropsSample1.txt">
<Button Click="createCustomMicaWindow_Click">Create Window with customizable Mica</Button>
</local:ControlExample>
<local:ControlExample HeaderText="Backdrop types:"
niels9001 marked this conversation as resolved.
Show resolved Hide resolved
CSharpSource="SystemBackdrops\SystemBackdropsSample1_cs.txt"
XamlSource="SystemBackdrops\SystemBackdropsSample1_xaml.txt">
<StackPanel>
<TextBlock TextWrapping="WrapWholeWords">
Mica is an opaque, dynamic material that incorporates theme and desktop wallpaper to paint the background of windows.
marcelwgn marked this conversation as resolved.
Show resolved Hide resolved
You can apply Mica as your application backdrop to create a visual hierarchy, aiding productivity, by increasing clarity about which window is in focus.
Mica is specifically designed for app performance as it only samples the desktop wallpaper once to create its visualization.
Mica is available for Windows 11 build 22000 or later. <LineBreak/> <LineBreak/>

<local:ControlExample HeaderText="Create a window with a built-in Desktop Acrylic system backdrop."
CSharpSource="SystemBackdrops\SystemBackdropsSample4.txt">
<local:ControlExample.Xaml>
<x:String xml:space="preserve">
// Option 1 - implement Acrylic with Xaml.
&lt;Window.SystemBackdrop&gt;
&lt;DesktopAcrylicBackdrop /&gt;
&lt;/Window.SystemBackdrop&gt;
</x:String>
</local:ControlExample.Xaml>
<Button Click="createBuiltInAcrylicWindow_Click">Create Window with built-in Acrylic</Button>
Mica Alt is a variant of Mica, with stronger tinting of the user's desktop background color.
You can apply Mica Alt as your app's backdrop to provide a deeper visual hierarchy than Mica, especially when creating an app with a tabbed title bar.
Mica Alt is available for Windows 11 build 22000 or later. <LineBreak/> <LineBreak/>
Acrylic is a semi-transparent material that replicates the effect of frosted glass. It's used only for transient, light-dismiss surfaces such as flyouts and context menus.
Acrylic's most noticeable characteristic is its transparency. There are two acrylic blend types that change what's visible through the material:
<LineBreak/><LineBreak/> Background acrylic reveals the desktop wallpaper and other windows that are behind the currently active app, adding depth between application windows while celebrating the user's personalization preferences.
<LineBreak/><LineBreak/> In-app acrylic adds a sense of depth within the app frame, providing both focus and hierarchy. (Inplemented with a AcrilicBrush in Xaml)
MGGSK marked this conversation as resolved.
Show resolved Hide resolved
</TextBlock>
<Button Margin="0 10 0 0" Click="createBuiltInWindow_Click">Show sample window</Button>
</StackPanel>
</local:ControlExample>

<local:ControlExample HeaderText="Create a window with a customizable Desktop Acrylic system backdrop."
<local:ControlExample HeaderText="MicaController:"
niels9001 marked this conversation as resolved.
Show resolved Hide resolved
CSharpSource="SystemBackdrops\SystemBackdropsSample2.txt">
<Button Click="createCustomDesktopAcrylicWindow_Click">Create Window with customizable Desktop Acrylic</Button>
<StackPanel>
<TextBlock TextWrapping="WrapWholeWords">
Manages rendering and system policy for the mica material. The MicaController class provides a very customizable way to apply the Mica material to a app.
MGGSK marked this conversation as resolved.
Show resolved Hide resolved
This is a list of properties that can be modified: FallbackColor, Kind (Can also be set using the MicaBackdrop class), LuminosityOpacity, State, TintColor and the TintOpacity.
</TextBlock>
<Button Margin="0 10 0 0" Click="createCustomMicaWindow_Click">Show sample window</Button>
</StackPanel>
</local:ControlExample>

<local:ControlExample HeaderText="DesktopAcrylicController:"
niels9001 marked this conversation as resolved.
Show resolved Hide resolved
CSharpSource="SystemBackdrops\SystemBackdropsSample3.txt">
niels9001 marked this conversation as resolved.
Show resolved Hide resolved
<StackPanel>
<TextBlock TextWrapping="WrapWholeWords">
Manages rendering and system policy for the background acrylic material. Acrylic has the same level of customization as Mica, but the type (Base / Thin) can't be changed using the DesktopAcrylicBackdrop class.
If you wan't to use Acrylic Thin in your app you have to use the DesktopAcrylicController class. There are 2 types of Acrylic: Base and Thin. The DesktopAcrylicBackdrop class uses a version of the Base type with less dimming.
niels9001 marked this conversation as resolved.
Show resolved Hide resolved
</TextBlock>
<Button Margin="0 10 0 0" Click="createCustomDesktopAcrylicWindow_Click">Show sample window</Button>
</StackPanel>
</local:ControlExample>

<local:ControlExample HeaderText="Helper class to ensure a Windows.System.DispatcherQueue exists."
<local:ControlExample HeaderText="WindowsSystemDispatcherQueueHelper: "
niels9001 marked this conversation as resolved.
Show resolved Hide resolved
CSharpSource="SystemBackdrops\SystemBackdropsEnsureSystemDQC.txt">
<TextBlock Text="A Windows.System.DispatcherQueue must exist on the thread to use MicaController or DesktopAcrylicController. This helper class exposes and uses the underlying create function." TextWrapping="WrapWholeWords" />
<TextBlock Text="A DispatcherQueue must exist on the thread to use a Mica or DesktopAcrylicController. This helper class improts and uses the underlying create function." TextWrapping="WrapWholeWords" />
MGGSK marked this conversation as resolved.
Show resolved Hide resolved
</local:ControlExample>
</StackPanel>
</Page>
42 changes: 20 additions & 22 deletions WinUIGallery/ControlPages/SystemBackdropsPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,48 +7,46 @@
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
using WinUIGallery.Helper;
using System;
using Microsoft.UI;
using Microsoft.UI.Windowing;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
using WinUIGallery.SamplePages;

namespace WinUIGallery.ControlPages
{
public sealed partial class SystemBackdropsPage : Page
{
public SystemBackdropsPage()
{
this.InitializeComponent();
InitializeComponent();
}

private void createBuiltInMicaWindow_Click(object sender, RoutedEventArgs e)
private void createBuiltInWindow_Click(object sender, RoutedEventArgs e)
{
var newWindow = new WinUIGallery.SamplePages.SampleBuiltInSystemBackdropsWindow();
newWindow.Activate();
var buildInBackdropsWindow = new SampleBuiltInSystemBackdropsWindow();
buildInBackdropsWindow.SetBackdrop(SampleBuiltInSystemBackdropsWindow.BackdropType.Mica);
buildInBackdropsWindow.Activate();
}

private void createCustomMicaWindow_Click(object sender, RoutedEventArgs e)
{
var newWindow = new WinUIGallery.SamplePages.SampleSystemBackdropsWindow();
newWindow.SetBackdrop(WinUIGallery.SamplePages.SampleSystemBackdropsWindow.BackdropType.Mica);
newWindow.Activate();
}

private void createBuiltInAcrylicWindow_Click(object sender, RoutedEventArgs e)
{
var newWindow = new WinUIGallery.SamplePages.SampleSystemBackdropsWindow();
newWindow.SetBackdrop(WinUIGallery.SamplePages.SampleSystemBackdropsWindow.BackdropType.DesktopAcrylicBase);
newWindow.Activate();
var micaWindow = new SampleSystemBackdropsWindow();
micaWindow.AllowedBackdrops = [
SampleSystemBackdropsWindow.BackdropType.Mica,
SampleSystemBackdropsWindow.BackdropType.MicaAlt,
SampleSystemBackdropsWindow.BackdropType.None
];
micaWindow.Activate();
}

private void createCustomDesktopAcrylicWindow_Click(object sender, RoutedEventArgs e)
{
var newWindow = new WinUIGallery.SamplePages.SampleSystemBackdropsWindow();
newWindow.SetBackdrop(WinUIGallery.SamplePages.SampleSystemBackdropsWindow.BackdropType.DesktopAcrylicBase);
newWindow.Activate();
var acrylicWindow = new SampleSystemBackdropsWindow();
acrylicWindow.AllowedBackdrops = [
SampleSystemBackdropsWindow.BackdropType.Acrylic,
SampleSystemBackdropsWindow.BackdropType.AcrylicThin,
SampleSystemBackdropsWindow.BackdropType.None
];
acrylicWindow.Activate();
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
bool TrySetMicaBackdrop(bool useMicaAlt)
{
if (SystemBackdrops.MicaController.IsSupported())
{
MicaBackdrop micaBackdrop = new MicaBackdrop();
micaBackdrop.Kind = useMicaAlt ? MicaKind.BaseAlt : MicaKind.Base;
SystemBackdrop = micaBackdrop;

return true; // Succeeded.
}

return false; // Mica is not supported on this system.
}

bool TrySetDesktopAcrylicBackdrop()
{
if (DesktopAcrylicController.IsSupported())
{
DesktopAcrylicBackdrop DesktopAcrylicBackdrop = new DesktopAcrylicBackdrop();
SystemBackdrop = DesktopAcrylicBackdrop;

return true; // Succeeded.
}

return false; // DesktopAcrylic is not supported on this system.
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!-- Mica -->
<Window.SystemBackdrop>
<MicaBackdrop/>
</Window.SystemBackdrop>

<!-- Mica Alt -->
<Window.SystemBackdrop>
<MicaBackdrop Kind="BaseAlt"/>
</Window.SystemBackdrop>

<!-- Acrylic -->
<Window.SystemBackdrop>
<DesktopAcrylicBackdrop/>
<Window.SystemBackdrop>
Original file line number Diff line number Diff line change
@@ -1,73 +1,72 @@
using System.Runtime.InteropServices; // For DllImport
using WinRT; // required to support Window.As<ICompositionSupportsSystemBackdrop>()
using System.Runtime.InteropServices;
using WinRT;
using Microsoft.UI.Composition;
using Microsoft.UI.Composition.SystemBackdrops;

WindowsSystemDispatcherQueueHelper m_wsdqHelper; // See separate sample below for implementation
Microsoft.UI.Composition.SystemBackdrops.DesktopAcrylicController m_acrylicController;
Microsoft.UI.Composition.SystemBackdrops.SystemBackdropConfiguration m_configurationSource;
WindowsSystemDispatcherQueueHelper wsdqHelper; // See the helper class sample for the implementation
MicaController micaController;
SystemBackdropConfiguration configurationSource;

bool TrySetAcrylicBackdrop(bool useAcrylicThin)
bool TrySetMicaBackdrop(bool useMicaAlt)
{
if (Microsoft.UI.Composition.SystemBackdrops.DesktopAcrylicController.IsSupported())
if (MicaController.IsSupported())
{
m_wsdqHelper = new WindowsSystemDispatcherQueueHelper();
m_wsdqHelper.EnsureWindowsSystemDispatcherQueueController();
wsdqHelper = new WindowsSystemDispatcherQueueHelper();
wsdqHelper.EnsureWindowsSystemDispatcherQueueController();

// Hooking up the policy object
m_configurationSource = new Microsoft.UI.Composition.SystemBackdrops.SystemBackdropConfiguration();
this.Activated += Window_Activated;
this.Closed += Window_Closed;
((FrameworkElement)this.Content).ActualThemeChanged += Window_ThemeChanged;
configurationSource = new SystemBackdropConfiguration();
Activated += Window_Activated;
Closed += Window_Closed;
((FrameworkElement)Content).ActualThemeChanged += Window_ThemeChanged;

// Initial configuration state.
m_configurationSource.IsInputActive = true;
configurationSource.IsInputActive = true;
SetConfigurationSourceTheme();

m_acrylicController = new Microsoft.UI.Composition.SystemBackdrops.DesktopAcrylicController();

m_acrylicController.Kind = useAcrylicThin ? Microsoft.UI.Composition.SystemBackdrops.DesktopAcrylicKind.Thin : Microsoft.UI.Composition.SystemBackdrops.DesktopAcrylicKind.Base;
micaController = new MicaController();
micaController.Kind = useMicaAlt ? MicaKind.BaseAlt : MicaKind.Base;

// Enable the system backdrop.
// Note: Be sure to have "using WinRT;" to support the Window.As<...>() call.
m_acrylicController.AddSystemBackdropTarget(this.As<Microsoft.UI.Composition.ICompositionSupportsSystemBackdrop>());
m_acrylicController.SetSystemBackdropConfiguration(m_configurationSource);
micaController.AddSystemBackdropTarget(this.As<ICompositionSupportsSystemBackdrop>());
micaController.SetSystemBackdropConfiguration(configurationSource);
return true; // Succeeded.
}

return false; // Acrylic is not supported on this system.
return false; // Mica is not supported on this system.
}

private void Window_Activated(object sender, WindowActivatedEventArgs args)
{
m_configurationSource.IsInputActive = args.WindowActivationState != WindowActivationState.Deactivated;
configurationSource.IsInputActive = args.WindowActivationState != WindowActivationState.Deactivated;
}

private void Window_Closed(object sender, WindowEventArgs args)
{
// Make sure any Mica/Acrylic controller is disposed so it doesn't try to
// use this closed window.
if (m_acrylicController != null)
// Make sure any Mica/Acrylic controller is disposed
if (micaController != null)
{
m_acrylicController.Dispose();
m_acrylicController = null;
micaController.Dispose();
micaController = null;
}
this.Activated -= Window_Activated;
m_configurationSource = null;
configurationSource = null;
}

private void Window_ThemeChanged(FrameworkElement sender, object args)
{
if (m_configurationSource != null)
if (configurationSource != null)
{
SetConfigurationSourceTheme();
}
}

private void SetConfigurationSourceTheme()
{
switch (((FrameworkElement)this.Content).ActualTheme)
switch (((FrameworkElement)Content).ActualTheme)
{
case ElementTheme.Dark: m_configurationSource.Theme = Microsoft.UI.Composition.SystemBackdrops.SystemBackdropTheme.Dark; break;
case ElementTheme.Light: m_configurationSource.Theme = Microsoft.UI.Composition.SystemBackdrops.SystemBackdropTheme.Light; break;
case ElementTheme.Default: m_configurationSource.Theme = Microsoft.UI.Composition.SystemBackdrops.SystemBackdropTheme.Default; break;
case ElementTheme.Dark: configurationSource.Theme = SystemBackdropTheme.Dark; break;
case ElementTheme.Light: configurationSource.Theme = SystemBackdropTheme.Light; break;
case ElementTheme.Default: configurationSource.Theme = SystemBackdropTheme.Default; break;
}
}
Loading