CmdPal: Transparent window (#45159)

## Summary

This PR adds:
- Backdrop material customization
  - Alongside acrylic, the following options are now available:
  - Transparent background
  - Mica background
- Background material opacity
  - Lets you control how transparent the background is

## Pictures? Pictures!

<img width="1491" height="928" alt="image"
src="https://github.com/user-attachments/assets/ff4e9e06-fcf1-4f05-bc0a-fb70dc4f39be"
/>



https://github.com/user-attachments/assets/84e83279-afab-481e-b904-f054318c5d2f

<img width="977" height="628" alt="image"
src="https://github.com/user-attachments/assets/241a228d-af3f-448a-94a6-0a282218bd8c"
/>


## PR Checklist

- [x] Closes: #44197
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [ ] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end-user-facing strings can be localized
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx

<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
This commit is contained in:
Jiří Polášek
2026-02-09 20:42:01 +01:00
committed by GitHub
parent 7477b561a1
commit 095961402b
24 changed files with 1023 additions and 157 deletions

View File

@@ -288,7 +288,6 @@ internal sealed partial class BlurImageControl : Control
_effectBrush?.Dispose();
_effectBrush = effectFactory.CreateBrush();
// Set initial source
if (ImageSource is not null)
{
_imageBrush ??= _compositor.CreateSurfaceBrush();

View File

@@ -16,24 +16,38 @@
CornerRadius="8"
Translation="0,0,8">
<Grid>
<!-- Clear style: SolidColorBrush with computed alpha (window backdrop) -->
<Border
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
BorderBrush="{ThemeResource SurfaceStrokeColorDefaultBrush}"
BorderThickness="1"
Visibility="{x:Bind h:BindTransformers.NegateVisibility(ShowBackgroundImage), Mode=OneWay}">
Visibility="{x:Bind ClearVisibility, Mode=OneWay}">
<Border.Background>
<SolidColorBrush Color="{x:Bind EffectiveClearColor, Mode=OneWay}" />
</Border.Background>
</Border>
<!-- Acrylic/Mica style: AcrylicBrush with effective opacity (window backdrop) -->
<Border
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
BorderBrush="{ThemeResource SurfaceStrokeColorDefaultBrush}"
BorderThickness="1"
Visibility="{x:Bind AcrylicVisibility, Mode=OneWay}">
<Border.Background>
<AcrylicBrush
FallbackColor="{x:Bind PreviewBackgroundColor, Mode=OneWay}"
TintColor="{x:Bind PreviewBackgroundColor, Mode=OneWay}"
TintOpacity="{x:Bind PreviewBackgroundOpacity, Mode=OneWay}" />
TintOpacity="{x:Bind PreviewEffectiveOpacity, Mode=OneWay}" />
</Border.Background>
</Border>
<!-- Background image (inside window, on top of backdrop) -->
<local:BlurImageControl
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
BlurAmount="{x:Bind PreviewBackgroundImageBlurAmount, Mode=OneWay}"
ImageBrightness="{x:Bind PreviewBackgroundImageBrightness, Mode=OneWay}"
ImageOpacity="{x:Bind PreviewBackgroundImageOpacity, Mode=OneWay}"
ImageSource="{x:Bind PreviewBackgroundImageSource, Mode=OneWay}"
ImageStretch="{x:Bind ToStretch(PreviewBackgroundImageFit), Mode=OneWay}"
IsHitTestVisible="False"

View File

@@ -12,13 +12,11 @@ namespace Microsoft.CmdPal.UI.Controls;
public sealed partial class CommandPalettePreview : UserControl
{
public static readonly DependencyProperty PreviewBackgroundOpacityProperty = DependencyProperty.Register(nameof(PreviewBackgroundOpacity), typeof(double), typeof(CommandPalettePreview), new PropertyMetadata(0d));
public static readonly DependencyProperty PreviewBackgroundColorProperty = DependencyProperty.Register(nameof(PreviewBackgroundColor), typeof(Color), typeof(CommandPalettePreview), new PropertyMetadata(default(Color), OnBackdropPropertyChanged));
public static readonly DependencyProperty PreviewBackgroundColorProperty = DependencyProperty.Register(nameof(PreviewBackgroundColor), typeof(Color), typeof(CommandPalettePreview), new PropertyMetadata(default(Color)));
public static readonly DependencyProperty PreviewBackgroundImageSourceProperty = DependencyProperty.Register(nameof(PreviewBackgroundImageSource), typeof(ImageSource), typeof(CommandPalettePreview), new PropertyMetadata(null, OnBackgroundImageSourceChanged));
public static readonly DependencyProperty PreviewBackgroundImageSourceProperty = DependencyProperty.Register(nameof(PreviewBackgroundImageSource), typeof(ImageSource), typeof(CommandPalettePreview), new PropertyMetadata(null, PropertyChangedCallback));
public static readonly DependencyProperty PreviewBackgroundImageOpacityProperty = DependencyProperty.Register(nameof(PreviewBackgroundImageOpacity), typeof(int), typeof(CommandPalettePreview), new PropertyMetadata(0));
public static readonly DependencyProperty PreviewBackgroundImageOpacityProperty = DependencyProperty.Register(nameof(PreviewBackgroundImageOpacity), typeof(double), typeof(CommandPalettePreview), new PropertyMetadata(1.0));
public static readonly DependencyProperty PreviewBackgroundImageFitProperty = DependencyProperty.Register(nameof(PreviewBackgroundImageFit), typeof(BackgroundImageFit), typeof(CommandPalettePreview), new PropertyMetadata(default(BackgroundImageFit)));
@@ -30,7 +28,18 @@ public sealed partial class CommandPalettePreview : UserControl
public static readonly DependencyProperty PreviewBackgroundImageTintIntensityProperty = DependencyProperty.Register(nameof(PreviewBackgroundImageTintIntensity), typeof(int), typeof(CommandPalettePreview), new PropertyMetadata(0));
public static readonly DependencyProperty ShowBackgroundImageProperty = DependencyProperty.Register(nameof(ShowBackgroundImage), typeof(Visibility), typeof(CommandPalettePreview), new PropertyMetadata(Visibility.Collapsed));
public static readonly DependencyProperty ShowBackgroundImageProperty = DependencyProperty.Register(nameof(ShowBackgroundImage), typeof(Visibility), typeof(CommandPalettePreview), new PropertyMetadata(Visibility.Collapsed, OnVisibilityPropertyChanged));
public static readonly DependencyProperty PreviewBackdropStyleProperty = DependencyProperty.Register(nameof(PreviewBackdropStyle), typeof(BackdropStyle?), typeof(CommandPalettePreview), new PropertyMetadata(null, OnVisibilityPropertyChanged));
public static readonly DependencyProperty PreviewEffectiveOpacityProperty = DependencyProperty.Register(nameof(PreviewEffectiveOpacity), typeof(double), typeof(CommandPalettePreview), new PropertyMetadata(1.0, OnBackdropPropertyChanged));
// Computed read-only dependency properties
public static readonly DependencyProperty EffectiveClearColorProperty = DependencyProperty.Register(nameof(EffectiveClearColor), typeof(Color), typeof(CommandPalettePreview), new PropertyMetadata(default(Color)));
public static readonly DependencyProperty AcrylicVisibilityProperty = DependencyProperty.Register(nameof(AcrylicVisibility), typeof(Visibility), typeof(CommandPalettePreview), new PropertyMetadata(Visibility.Visible));
public static readonly DependencyProperty ClearVisibilityProperty = DependencyProperty.Register(nameof(ClearVisibility), typeof(Visibility), typeof(CommandPalettePreview), new PropertyMetadata(Visibility.Collapsed));
public BackgroundImageFit PreviewBackgroundImageFit
{
@@ -38,12 +47,6 @@ public sealed partial class CommandPalettePreview : UserControl
set { SetValue(PreviewBackgroundImageFitProperty, value); }
}
public double PreviewBackgroundOpacity
{
get { return (double)GetValue(PreviewBackgroundOpacityProperty); }
set { SetValue(PreviewBackgroundOpacityProperty, value); }
}
public Color PreviewBackgroundColor
{
get { return (Color)GetValue(PreviewBackgroundColorProperty); }
@@ -56,10 +59,10 @@ public sealed partial class CommandPalettePreview : UserControl
set { SetValue(PreviewBackgroundImageSourceProperty, value); }
}
public int PreviewBackgroundImageOpacity
public double PreviewBackgroundImageOpacity
{
get { return (int)GetValue(PreviewBackgroundImageOpacityProperty); }
set { SetValue(PreviewBackgroundImageOpacityProperty, value); }
get => (double)GetValue(PreviewBackgroundImageOpacityProperty);
set => SetValue(PreviewBackgroundImageOpacityProperty, value);
}
public double PreviewBackgroundImageBrightness
@@ -92,12 +95,48 @@ public sealed partial class CommandPalettePreview : UserControl
set => SetValue(ShowBackgroundImageProperty, value);
}
public BackdropStyle? PreviewBackdropStyle
{
get => (BackdropStyle?)GetValue(PreviewBackdropStyleProperty);
set => SetValue(PreviewBackdropStyleProperty, value);
}
/// <summary>
/// Gets or sets the effective opacity for the backdrop, pre-computed by the theme provider.
/// For Acrylic style: used directly as TintOpacity.
/// For Clear style: used to compute the alpha channel of the solid color.
/// </summary>
public double PreviewEffectiveOpacity
{
get => (double)GetValue(PreviewEffectiveOpacityProperty);
set => SetValue(PreviewEffectiveOpacityProperty, value);
}
// Computed read-only properties
public Color EffectiveClearColor
{
get => (Color)GetValue(EffectiveClearColorProperty);
private set => SetValue(EffectiveClearColorProperty, value);
}
public Visibility AcrylicVisibility
{
get => (Visibility)GetValue(AcrylicVisibilityProperty);
private set => SetValue(AcrylicVisibilityProperty, value);
}
public Visibility ClearVisibility
{
get => (Visibility)GetValue(ClearVisibilityProperty);
private set => SetValue(ClearVisibilityProperty, value);
}
public CommandPalettePreview()
{
InitializeComponent();
}
private static void PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
private static void OnBackgroundImageSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is not CommandPalettePreview preview)
{
@@ -107,7 +146,46 @@ public sealed partial class CommandPalettePreview : UserControl
preview.ShowBackgroundImage = e.NewValue is ImageSource ? Visibility.Visible : Visibility.Collapsed;
}
private double ToOpacity(int value) => value / 100.0;
private static void OnBackdropPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is not CommandPalettePreview preview)
{
return;
}
preview.UpdateComputedClearColor();
}
private static void OnVisibilityPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is not CommandPalettePreview preview)
{
return;
}
preview.UpdateComputedVisibilityProperties();
preview.UpdateComputedClearColor();
}
private void UpdateComputedClearColor()
{
EffectiveClearColor = Color.FromArgb(
(byte)(PreviewEffectiveOpacity * 255),
PreviewBackgroundColor.R,
PreviewBackgroundColor.G,
PreviewBackgroundColor.B);
}
private void UpdateComputedVisibilityProperties()
{
var config = BackdropStyles.Get(PreviewBackdropStyle ?? BackdropStyle.Acrylic);
// Show backdrop effect based on style (on top of any background image)
AcrylicVisibility = config.PreviewBrush == PreviewBrushKind.Acrylic
? Visibility.Visible : Visibility.Collapsed;
ClearVisibility = config.PreviewBrush == PreviewBrushKind.Solid
? Visibility.Visible : Visibility.Collapsed;
}
private double ToTintIntensity(int value) => value / 100.0;

View File

@@ -22,7 +22,7 @@
VerticalAlignment="Stretch"
BlurAmount="{x:Bind ViewModel.BackgroundImageBlurAmount, Mode=OneWay}"
ImageBrightness="{x:Bind ViewModel.BackgroundImageBrightness, Mode=OneWay}"
ImageOpacity="{x:Bind ViewModel.BackgroundImageOpacity, Mode=OneWay}"
ImageOpacity="{x:Bind ViewModel.EffectiveImageOpacity, Mode=OneWay}"
ImageSource="{x:Bind ViewModel.BackgroundImageSource, Mode=OneWay}"
ImageStretch="{x:Bind ViewModel.BackgroundImageStretch, Mode=OneWay}"
IsHitTestVisible="False"

View File

@@ -31,6 +31,7 @@ using Windows.ApplicationModel.Activation;
using Windows.Foundation;
using Windows.Graphics;
using Windows.System;
using Windows.UI;
using Windows.Win32;
using Windows.Win32.Foundation;
using Windows.Win32.Graphics.Dwm;
@@ -80,7 +81,9 @@ public sealed partial class MainWindow : WindowEx,
private int _sessionErrorCount;
private DesktopAcrylicController? _acrylicController;
private MicaController? _micaController;
private SystemBackdropConfiguration? _configurationSource;
private bool _isUpdatingBackdrop;
private TimeSpan _autoGoHomeInterval = Timeout.InfiniteTimeSpan;
private WindowPosition _currentWindowPosition = new();
@@ -109,7 +112,7 @@ public sealed partial class MainWindow : WindowEx,
CommandPaletteHost.SetHostHwnd((ulong)_hwnd.Value);
}
SetAcrylic();
InitializeBackdropSupport();
_hiddenOwnerBehavior.ShowInTaskbar(this, Debugger.IsAttached);
@@ -158,7 +161,7 @@ public sealed partial class MainWindow : WindowEx,
App.Current.Services.GetService<SettingsModel>()!.SettingsChanged += SettingsChangedHandler;
// Make sure that we update the acrylic theme when the OS theme changes
RootElement.ActualThemeChanged += (s, e) => DispatcherQueue.TryEnqueue(UpdateAcrylic);
RootElement.ActualThemeChanged += (s, e) => DispatcherQueue.TryEnqueue(UpdateBackdrop);
// Hardcoding event name to avoid bringing in the PowerToys.interop dependency. Event name must match CMDPAL_SHOW_EVENT from shared_constants.h
NativeEventWaiter.WaitForEventLoop("Local\\PowerToysCmdPal-ShowEvent-62336fcd-8611-4023-9b30-091a6af4cc5a", () =>
@@ -185,7 +188,7 @@ public sealed partial class MainWindow : WindowEx,
private void ThemeServiceOnThemeChanged(object? sender, ThemeChangedEventArgs e)
{
UpdateAcrylic();
UpdateBackdrop();
}
private static void LocalKeyboardListener_OnKeyPressed(object? sender, LocalKeyboardListenerKeyPressedEventArgs e)
@@ -280,48 +283,170 @@ public sealed partial class MainWindow : WindowEx,
_autoGoHomeTimer.Interval = _autoGoHomeInterval;
}
private void SetAcrylic()
private void InitializeBackdropSupport()
{
if (DesktopAcrylicController.IsSupported())
if (DesktopAcrylicController.IsSupported() || MicaController.IsSupported())
{
// Hooking up the policy object.
_configurationSource = new SystemBackdropConfiguration
{
// Initial configuration state.
IsInputActive = true,
};
UpdateAcrylic();
}
}
private void UpdateAcrylic()
private void UpdateBackdrop()
{
// Prevent re-entrance when backdrop changes trigger ActualThemeChanged
if (_isUpdatingBackdrop)
{
return;
}
_isUpdatingBackdrop = true;
var backdrop = _themeService.Current.BackdropParameters;
var isImageMode = ViewModel.ShowBackgroundImage;
var config = BackdropStyles.Get(backdrop.Style);
try
{
if (_acrylicController != null)
switch (config.ControllerKind)
{
_acrylicController.RemoveAllSystemBackdropTargets();
_acrylicController.Dispose();
case BackdropControllerKind.Solid:
CleanupBackdropControllers();
var tintColor = Color.FromArgb(
(byte)(backdrop.EffectiveOpacity * 255),
backdrop.TintColor.R,
backdrop.TintColor.G,
backdrop.TintColor.B);
SetupTransparentBackdrop(tintColor);
break;
case BackdropControllerKind.Mica:
case BackdropControllerKind.MicaAlt:
SetupMica(backdrop, isImageMode, config.ControllerKind);
break;
case BackdropControllerKind.Acrylic:
case BackdropControllerKind.AcrylicThin:
default:
SetupDesktopAcrylic(backdrop, isImageMode, config.ControllerKind);
break;
}
var backdrop = _themeService.Current.BackdropParameters;
_acrylicController = new DesktopAcrylicController
{
TintColor = backdrop.TintColor,
TintOpacity = backdrop.TintOpacity,
FallbackColor = backdrop.FallbackColor,
LuminosityOpacity = backdrop.LuminosityOpacity,
};
// Enable the system backdrop.
// Note: Be sure to have "using WinRT;" to support the Window.As<...>() call.
_acrylicController.AddSystemBackdropTarget(this.As<ICompositionSupportsSystemBackdrop>());
_acrylicController.SetSystemBackdropConfiguration(_configurationSource);
}
catch (Exception ex)
{
Logger.LogError("Failed to update backdrop", ex);
}
finally
{
_isUpdatingBackdrop = false;
}
}
private void SetupTransparentBackdrop(Color tintColor)
{
if (SystemBackdrop is TransparentTintBackdrop existingBackdrop)
{
existingBackdrop.TintColor = tintColor;
}
else
{
SystemBackdrop = new TransparentTintBackdrop { TintColor = tintColor };
}
}
private void CleanupBackdropControllers()
{
if (_acrylicController is not null)
{
_acrylicController.RemoveAllSystemBackdropTargets();
_acrylicController.Dispose();
_acrylicController = null;
}
if (_micaController is not null)
{
_micaController.RemoveAllSystemBackdropTargets();
_micaController.Dispose();
_micaController = null;
}
}
private void SetupDesktopAcrylic(BackdropParameters backdrop, bool isImageMode, BackdropControllerKind kind)
{
CleanupBackdropControllers();
// Fall back to solid color if acrylic not supported
if (_configurationSource is null || !DesktopAcrylicController.IsSupported())
{
SetupTransparentBackdrop(backdrop.FallbackColor);
return;
}
// DesktopAcrylicController and SystemBackdrop can't be active simultaneously
SystemBackdrop = null;
// Image mode: no tint here, BlurImageControl handles it (avoids double-tinting)
var effectiveTintOpacity = isImageMode
? 0.0f
: backdrop.EffectiveOpacity;
_acrylicController = new DesktopAcrylicController
{
Kind = kind == BackdropControllerKind.AcrylicThin
? DesktopAcrylicKind.Thin
: DesktopAcrylicKind.Default,
TintColor = backdrop.TintColor,
TintOpacity = effectiveTintOpacity,
FallbackColor = backdrop.FallbackColor,
LuminosityOpacity = backdrop.EffectiveLuminosityOpacity,
};
// Requires "using WinRT;" for Window.As<>()
_acrylicController.AddSystemBackdropTarget(this.As<ICompositionSupportsSystemBackdrop>());
_acrylicController.SetSystemBackdropConfiguration(_configurationSource);
}
private void SetupMica(BackdropParameters backdrop, bool isImageMode, BackdropControllerKind kind)
{
CleanupBackdropControllers();
// Fall back to solid color if Mica not supported
if (_configurationSource is null || !MicaController.IsSupported())
{
SetupTransparentBackdrop(backdrop.FallbackColor);
return;
}
// MicaController and SystemBackdrop can't be active simultaneously
SystemBackdrop = null;
_configurationSource.Theme = _themeService.Current.Theme == ElementTheme.Dark
? SystemBackdropTheme.Dark
: SystemBackdropTheme.Light;
var hasColorization = _themeService.Current.HasColorization || isImageMode;
_micaController = new MicaController
{
Kind = kind == BackdropControllerKind.MicaAlt
? MicaKind.BaseAlt
: MicaKind.Base,
};
// Only set tint properties when colorization is active
// Otherwise let system handle light/dark theme defaults automatically
if (hasColorization)
{
// Image mode: no tint here, BlurImageControl handles it (avoids double-tinting)
_micaController.TintColor = backdrop.TintColor;
_micaController.TintOpacity = isImageMode ? 0.0f : backdrop.EffectiveOpacity;
_micaController.FallbackColor = backdrop.FallbackColor;
_micaController.LuminosityOpacity = backdrop.EffectiveLuminosityOpacity;
}
_micaController.AddSystemBackdropTarget(this.As<ICompositionSupportsSystemBackdrop>());
_micaController.SetSystemBackdropConfiguration(_configurationSource);
}
private void ShowHwnd(IntPtr hwndValue, MonitorBehavior target)
@@ -637,12 +762,8 @@ public sealed partial class MainWindow : WindowEx,
private void DisposeAcrylic()
{
if (_acrylicController is not null)
{
_acrylicController.Dispose();
_acrylicController = null!;
_configurationSource = null!;
}
CleanupBackdropControllers();
_configurationSource = null!;
}
// Updates our window s.t. the top of the window is draggable.

View File

@@ -4,6 +4,7 @@
using CommunityToolkit.WinUI.Helpers;
using Microsoft.CmdPal.UI.Helpers;
using Microsoft.CmdPal.UI.ViewModels;
using Microsoft.CmdPal.UI.ViewModels.Services;
using Microsoft.UI.Xaml;
using Windows.UI;
@@ -34,7 +35,7 @@ internal sealed class ColorfulThemeProvider : IThemeProvider
_uiSettings = uiSettings;
}
public AcrylicBackdropParameters GetAcrylicBackdrop(ThemeContext context)
public BackdropParameters GetBackdropParameters(ThemeContext context)
{
var isLight = context.Theme == ElementTheme.Light ||
(context.Theme == ElementTheme.Default &&
@@ -53,7 +54,26 @@ internal sealed class ColorfulThemeProvider : IThemeProvider
var colorIntensity = isLight ? 0.6f * colorIntensityUser : colorIntensityUser;
var effectiveBgColor = ColorBlender.Blend(baseColor, blended, colorIntensity);
return new AcrylicBackdropParameters(effectiveBgColor, effectiveBgColor, 0.8f, 0.8f);
var transparencyMode = context.BackdropStyle ?? BackdropStyle.Acrylic;
var config = BackdropStyles.Get(transparencyMode);
// For colorful theme, boost tint opacity to show color better through blur
// But not for styles with fixed opacity (Mica) - they handle their own opacity
var baseTintOpacity = config.ControllerKind == BackdropControllerKind.Solid || !config.SupportsOpacity
? (float?)null // Use default
: Math.Max(config.BaseTintOpacity, 0.8f);
var effectiveOpacity = config.ComputeEffectiveOpacity(context.BackdropOpacity, baseTintOpacity);
var effectiveLuminosityOpacity = config.SupportsOpacity
? config.BaseLuminosityOpacity * context.BackdropOpacity
: config.BaseLuminosityOpacity;
return new BackdropParameters(
TintColor: effectiveBgColor,
FallbackColor: effectiveBgColor,
EffectiveOpacity: effectiveOpacity,
EffectiveLuminosityOpacity: effectiveLuminosityOpacity,
Style: transparencyMode);
}
private static class ColorBlender

View File

@@ -8,14 +8,14 @@ using Microsoft.CmdPal.UI.ViewModels.Services;
namespace Microsoft.CmdPal.UI.Services;
/// <summary>
/// Provides theme identification, resource path resolution, and creation of acrylic
/// backdrop parameters based on the current <see cref="ThemeContext"/>.
/// Provides theme identification, resource path resolution, and creation of backdrop
/// parameters based on the current <see cref="ThemeContext"/>.
/// </summary>
/// <remarks>
/// Implementations should expose a stable <see cref="ThemeKey"/> and a valid XAML resource
/// dictionary path via <see cref="ResourcePath"/>. The
/// <see cref="GetAcrylicBackdrop(ThemeContext)"/> method computes
/// <see cref="AcrylicBackdropParameters"/> using the supplied theme context.
/// <see cref="GetBackdropParameters(ThemeContext)"/> method computes
/// <see cref="BackdropParameters"/> using the supplied theme context.
/// </remarks>
internal interface IThemeProvider
{
@@ -30,9 +30,9 @@ internal interface IThemeProvider
string ResourcePath { get; }
/// <summary>
/// Creates acrylic backdrop parameters based on the provided theme context.
/// Creates backdrop parameters based on the provided theme context.
/// </summary>
/// <param name="context">The current theme context, including theme, tint, and optional background details.</param>
/// <returns>The computed <see cref="AcrylicBackdropParameters"/> for the backdrop.</returns>
AcrylicBackdropParameters GetAcrylicBackdrop(ThemeContext context);
/// <param name="context">The current theme context, including theme, tint, transparency mode, and optional background details.</param>
/// <returns>The computed <see cref="BackdropParameters"/> for the backdrop.</returns>
BackdropParameters GetBackdropParameters(ThemeContext context);
}

View File

@@ -2,6 +2,7 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Microsoft.CmdPal.UI.ViewModels;
using Microsoft.CmdPal.UI.ViewModels.Services;
using Microsoft.UI.Xaml;
using Windows.UI;
@@ -28,16 +29,28 @@ internal sealed class NormalThemeProvider : IThemeProvider
public string ResourcePath => "ms-appx:///Styles/Theme.Normal.xaml";
public AcrylicBackdropParameters GetAcrylicBackdrop(ThemeContext context)
public BackdropParameters GetBackdropParameters(ThemeContext context)
{
var isLight = context.Theme == ElementTheme.Light ||
(context.Theme == ElementTheme.Default &&
_uiSettings.GetColorValue(UIColorType.Background).R > 128);
return new AcrylicBackdropParameters(
var backdropStyle = context.BackdropStyle ?? BackdropStyle.Acrylic;
var config = BackdropStyles.Get(backdropStyle);
// Apply light/dark theme adjustment to luminosity
var baseLuminosityOpacity = isLight
? config.BaseLuminosityOpacity
: Math.Min(config.BaseLuminosityOpacity + 0.06f, 1.0f);
var effectiveOpacity = config.ComputeEffectiveOpacity(context.BackdropOpacity);
var effectiveLuminosityOpacity = baseLuminosityOpacity * context.BackdropOpacity;
return new BackdropParameters(
TintColor: isLight ? LightBaseColor : DarkBaseColor,
FallbackColor: isLight ? LightBaseColor : DarkBaseColor,
TintOpacity: 0.5f,
LuminosityOpacity: isLight ? 0.9f : 0.96f);
EffectiveOpacity: effectiveOpacity,
EffectiveLuminosityOpacity: effectiveLuminosityOpacity,
Style: backdropStyle);
}
}

View File

@@ -2,12 +2,16 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Microsoft.CmdPal.UI.ViewModels;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Media;
using Windows.UI;
namespace Microsoft.CmdPal.UI.Services;
/// <summary>
/// Input parameters for theme computation, passed to theme providers.
/// </summary>
internal sealed record ThemeContext
{
public ElementTheme Theme { get; init; }
@@ -21,4 +25,8 @@ internal sealed record ThemeContext
public double BackgroundImageOpacity { get; init; }
public int? ColorIntensity { get; init; }
public BackdropStyle? BackdropStyle { get; init; }
public float BackdropOpacity { get; init; } = 1.0f;
}

View File

@@ -72,10 +72,13 @@ internal sealed partial class ThemeService : IThemeService, IDisposable
}
// provider selection
var intensity = Math.Clamp(_settings.CustomThemeColorIntensity, 0, 100);
IThemeProvider provider = intensity > 0 && _settings.ColorizationMode is ColorizationMode.CustomColor or ColorizationMode.WindowsAccentColor or ColorizationMode.Image
? _colorfulThemeProvider
: _normalThemeProvider;
var themeColorIntensity = Math.Clamp(_settings.CustomThemeColorIntensity, 0, 100);
var imageTintIntensity = Math.Clamp(_settings.BackgroundImageTintIntensity, 0, 100);
var effectiveColorIntensity = _settings.ColorizationMode == ColorizationMode.Image
? imageTintIntensity
: themeColorIntensity;
IThemeProvider provider = UseColorfulProvider(effectiveColorIntensity) ? _colorfulThemeProvider : _normalThemeProvider;
// Calculate values
var tint = _settings.ColorizationMode switch
@@ -96,32 +99,39 @@ internal sealed partial class ThemeService : IThemeService, IDisposable
};
var opacity = Math.Clamp(_settings.BackgroundImageOpacity, 0, 100) / 100.0;
// create context and offload to actual theme provider
// create input and offload to actual theme provider
var context = new ThemeContext
{
Tint = tint,
ColorIntensity = intensity,
ColorIntensity = effectiveColorIntensity,
Theme = effectiveTheme,
BackgroundImageSource = imageSource,
BackgroundImageStretch = stretch,
BackgroundImageOpacity = opacity,
BackdropStyle = _settings.BackdropStyle,
BackdropOpacity = Math.Clamp(_settings.BackdropOpacity, 0, 100) / 100f,
};
var backdrop = provider.GetAcrylicBackdrop(context);
var backdrop = provider.GetBackdropParameters(context);
var blur = _settings.BackgroundImageBlurAmount;
var brightness = _settings.BackgroundImageBrightness;
// Create public snapshot (no provider!)
var hasColorization = effectiveColorIntensity > 0
&& _settings.ColorizationMode is ColorizationMode.CustomColor or ColorizationMode.WindowsAccentColor or ColorizationMode.Image;
var snapshot = new ThemeSnapshot
{
Tint = tint,
TintIntensity = intensity / 100f,
TintIntensity = effectiveColorIntensity / 100f,
Theme = effectiveTheme,
BackgroundImageSource = imageSource,
BackgroundImageStretch = stretch,
BackgroundImageOpacity = opacity,
BackdropParameters = backdrop,
BackdropOpacity = context.BackdropOpacity,
BlurAmount = blur,
BackgroundBrightness = brightness / 100f,
HasColorization = hasColorization,
};
// Bundle with provider for internal use
@@ -138,6 +148,12 @@ internal sealed partial class ThemeService : IThemeService, IDisposable
ThemeChanged?.Invoke(this, new ThemeChangedEventArgs());
}
private bool UseColorfulProvider(int effectiveColorIntensity)
{
return _settings.ColorizationMode == ColorizationMode.Image
|| (effectiveColorIntensity > 0 && _settings.ColorizationMode is ColorizationMode.CustomColor or ColorizationMode.WindowsAccentColor);
}
private static BitmapImage? LoadImageSafe(string? path)
{
if (string.IsNullOrWhiteSpace(path))
@@ -195,13 +211,15 @@ internal sealed partial class ThemeService : IThemeService, IDisposable
{
Tint = Colors.Transparent,
Theme = ElementTheme.Light,
BackdropParameters = new AcrylicBackdropParameters(Colors.Black, Colors.Black, 0.5f, 0.5f),
BackdropParameters = new BackdropParameters(Colors.Black, Colors.Black, EffectiveOpacity: 0.5f, EffectiveLuminosityOpacity: 0.5f),
BackdropOpacity = 1.0f,
BackgroundImageOpacity = 1,
BackgroundImageSource = null,
BackgroundImageStretch = Stretch.Fill,
BlurAmount = 0,
TintIntensity = 1.0f,
BackgroundBrightness = 0,
HasColorization = false,
},
Provider = _normalThemeProvider,
};

View File

@@ -22,18 +22,50 @@
HorizontalAlignment="Stretch"
Spacing="{StaticResource SettingsCardSpacing}">
<ptControls:ScreenPreview Margin="0,0,0,16" HorizontalAlignment="Left">
<ptControls:CommandPalettePreview
PreviewBackgroundColor="{x:Bind ViewModel.Appearance.EffectiveBackdrop.TintColor, Mode=OneWay}"
PreviewBackgroundImageBlurAmount="{x:Bind ViewModel.Appearance.EffectiveBackgroundImageBlurAmount, Mode=OneWay}"
PreviewBackgroundImageBrightness="{x:Bind ViewModel.Appearance.EffectiveBackgroundImageBrightness, Mode=OneWay}"
PreviewBackgroundImageFit="{x:Bind ViewModel.Appearance.BackgroundImageFit, Mode=OneWay}"
PreviewBackgroundImageSource="{x:Bind ViewModel.Appearance.EffectiveBackgroundImageSource, Mode=OneWay}"
PreviewBackgroundImageTint="{x:Bind ViewModel.Appearance.EffectiveThemeColor, Mode=OneWay}"
PreviewBackgroundImageTintIntensity="{x:Bind ViewModel.Appearance.ColorIntensity, Mode=OneWay}"
PreviewBackgroundOpacity="{x:Bind ViewModel.Appearance.EffectiveBackdrop.TintOpacity, Mode=OneWay}"
RequestedTheme="{x:Bind ViewModel.Appearance.EffectiveTheme, Mode=OneWay}" />
</ptControls:ScreenPreview>
<StackPanel
Margin="0,0,0,16"
HorizontalAlignment="Left"
Orientation="Horizontal"
Spacing="16">
<ptControls:ScreenPreview>
<ptControls:CommandPalettePreview
PreviewBackdropStyle="{x:Bind ViewModel.Appearance.EffectiveBackdropStyle, Mode=OneWay}"
PreviewBackgroundColor="{x:Bind ViewModel.Appearance.EffectiveBackdrop.TintColor, Mode=OneWay}"
PreviewBackgroundImageBlurAmount="{x:Bind ViewModel.Appearance.EffectiveBackgroundImageBlurAmount, Mode=OneWay}"
PreviewBackgroundImageBrightness="{x:Bind ViewModel.Appearance.EffectiveBackgroundImageBrightness, Mode=OneWay}"
PreviewBackgroundImageFit="{x:Bind ViewModel.Appearance.BackgroundImageFit, Mode=OneWay}"
PreviewBackgroundImageOpacity="{x:Bind ViewModel.Appearance.EffectiveImageOpacity, Mode=OneWay}"
PreviewBackgroundImageSource="{x:Bind ViewModel.Appearance.EffectiveBackgroundImageSource, Mode=OneWay}"
PreviewBackgroundImageTint="{x:Bind ViewModel.Appearance.EffectiveThemeColor, Mode=OneWay}"
PreviewBackgroundImageTintIntensity="{x:Bind ViewModel.Appearance.EffectiveTintIntensity, Mode=OneWay}"
PreviewEffectiveOpacity="{x:Bind ViewModel.Appearance.EffectiveBackdrop.EffectiveOpacity, Mode=OneWay}"
RequestedTheme="{x:Bind ViewModel.Appearance.EffectiveTheme, Mode=OneWay}" />
</ptControls:ScreenPreview>
<StackPanel VerticalAlignment="Bottom" Spacing="8">
<Button
x:Uid="Settings_AppearancePage_OpenCommandPaletteButton"
MinWidth="200"
HorizontalContentAlignment="Left"
Click="OpenCommandPalette_Click"
Style="{StaticResource SubtleButtonStyle}">
<StackPanel Orientation="Horizontal" Spacing="8">
<FontIcon FontSize="16" Glyph="&#xE8A7;" />
<TextBlock x:Uid="Settings_AppearancePage_OpenCommandPaletteButton_Text" />
</StackPanel>
</Button>
<Button
x:Uid="Settings_AppearancePage_ResetAppearanceButton"
MinWidth="200"
HorizontalContentAlignment="Left"
Command="{x:Bind ViewModel.Appearance.ResetAppearanceSettingsCommand}"
Style="{StaticResource SubtleButtonStyle}">
<StackPanel Orientation="Horizontal" Spacing="8">
<FontIcon FontSize="16" Glyph="&#xE72C;" />
<TextBlock x:Uid="Settings_AppearancePage_ResetAppearanceButton_Text" />
</StackPanel>
</Button>
</StackPanel>
</StackPanel>
<controls:SettingsCard x:Uid="Settings_GeneralPage_AppTheme_SettingsCard" HeaderIcon="{ui:FontIcon Glyph=&#xE793;}">
<ComboBox MinWidth="{StaticResource SettingActionControlMinWidth}" SelectedIndex="{x:Bind ViewModel.Appearance.ThemeIndex, Mode=TwoWay}">
@@ -62,19 +94,67 @@
</ComboBox>
</controls:SettingsCard>
<controls:SettingsExpander
x:Uid="Settings_GeneralPage_BackdropStyle_SettingsCard"
HeaderIcon="{ui:FontIcon Glyph=&#xF5EF;}"
IsExpanded="{x:Bind ViewModel.Appearance.IsBackdropOpacityVisible, Mode=OneWay}">
<ComboBox MinWidth="{StaticResource SettingActionControlMinWidth}" SelectedIndex="{x:Bind ViewModel.Appearance.BackdropStyleIndex, Mode=TwoWay}">
<ComboBoxItem x:Uid="Settings_GeneralPage_BackdropStyle_Acrylic" />
<ComboBoxItem x:Uid="Settings_GeneralPage_BackdropStyle_Transparent" />
<ComboBoxItem x:Uid="Settings_GeneralPage_BackdropStyle_Mica" />
<!-- Hidden: preview not working well, kept to preserve index mapping -->
<ComboBoxItem x:Uid="Settings_GeneralPage_BackdropStyle_AcrylicThin" Visibility="Collapsed" />
<ComboBoxItem x:Uid="Settings_GeneralPage_BackdropStyle_MicaAlt" />
</ComboBox>
<controls:SettingsExpander.Items>
<!-- Mica description (no opacity control) -->
<controls:SettingsCard
x:Uid="Settings_GeneralPage_MicaBackdrop_SettingsCard"
HorizontalContentAlignment="Stretch"
ContentAlignment="Vertical"
Visibility="{x:Bind ViewModel.Appearance.IsMicaBackdropDescriptionVisible, Mode=OneWay}">
<TextBlock
x:Uid="Settings_GeneralPage_MicaBackdrop_DescriptionTextBlock"
Margin="24"
HorizontalAlignment="Stretch"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
HorizontalTextAlignment="Center"
TextAlignment="Center"
TextWrapping="WrapWholeWords" />
</controls:SettingsCard>
<!-- Opacity slider (for non-Mica styles) -->
<controls:SettingsCard x:Uid="Settings_GeneralPage_BackdropOpacity_SettingsCard" Visibility="{x:Bind ViewModel.Appearance.IsBackdropOpacityVisible, Mode=OneWay}">
<Slider
MinWidth="{StaticResource SettingActionControlMinWidth}"
Maximum="100"
Minimum="0"
StepFrequency="1"
Value="{x:Bind ViewModel.Appearance.BackdropOpacity, Mode=TwoWay}" />
</controls:SettingsCard>
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
<controls:SettingsExpander
x:Uid="Settings_GeneralPage_Background_SettingsExpander"
HeaderIcon="{ui:FontIcon Glyph=&#xE790;}"
IsEnabled="{x:Bind ViewModel.Appearance.IsBackgroundSettingsEnabled, Mode=OneWay}"
IsExpanded="{x:Bind ViewModel.Appearance.IsColorizationDetailsExpanded, Mode=TwoWay}">
<ComboBox
x:Uid="Settings_GeneralPage_ColorizationMode"
MinWidth="{StaticResource SettingActionControlMinWidth}"
SelectedIndex="{x:Bind ViewModel.Appearance.ColorizationModeIndex, Mode=TwoWay}">
<ComboBoxItem x:Uid="Settings_GeneralPage_ColorizationMode_None" />
<ComboBoxItem x:Uid="Settings_GeneralPage_ColorizationMode_WindowsAccent" />
<ComboBoxItem x:Uid="Settings_GeneralPage_ColorizationMode_CustomColor" />
<ComboBoxItem x:Uid="Settings_GeneralPage_ColorizationMode_Image" />
</ComboBox>
<Grid>
<ComboBox
x:Uid="Settings_GeneralPage_ColorizationMode"
MinWidth="{StaticResource SettingActionControlMinWidth}"
SelectedIndex="{x:Bind ViewModel.Appearance.ColorizationModeIndex, Mode=TwoWay}"
Visibility="{x:Bind ViewModel.Appearance.IsBackgroundSettingsEnabled, Mode=OneWay}">
<ComboBoxItem x:Uid="Settings_GeneralPage_ColorizationMode_None" />
<ComboBoxItem x:Uid="Settings_GeneralPage_ColorizationMode_WindowsAccent" />
<ComboBoxItem x:Uid="Settings_GeneralPage_ColorizationMode_CustomColor" />
<ComboBoxItem x:Uid="Settings_GeneralPage_ColorizationMode_Image" />
</ComboBox>
<TextBlock
x:Uid="Settings_GeneralPage_Background_NotAvailable"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Visibility="{x:Bind ViewModel.Appearance.IsBackgroundNotAvailableVisible, Mode=OneWay}" />
</Grid>
<controls:SettingsExpander.Items>
<!-- none -->
<controls:SettingsCard
@@ -155,7 +235,7 @@
PaletteColors="{x:Bind ViewModel.Appearance.Swatches}"
SelectedColor="{x:Bind ViewModel.Appearance.ThemeColor, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard x:Uid="Settings_GeneralPage_BackgroundTintIntensity_SettingsCard" Visibility="{x:Bind ViewModel.Appearance.IsCustomTintIntensityVisible, Mode=OneWay}">
<controls:SettingsCard x:Uid="Settings_GeneralPage_BackgroundTintIntensity_SettingsCard" Visibility="{x:Bind ViewModel.Appearance.IsColorIntensityVisible, Mode=OneWay}">
<Slider
MinWidth="{StaticResource SettingActionControlMinWidth}"
Maximum="100"
@@ -163,9 +243,17 @@
StepFrequency="1"
Value="{x:Bind ViewModel.Appearance.ColorIntensity, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard x:Uid="Settings_GeneralPage_ImageTintIntensity_SettingsCard" Visibility="{x:Bind ViewModel.Appearance.IsImageTintIntensityVisible, Mode=OneWay}">
<Slider
MinWidth="{StaticResource SettingActionControlMinWidth}"
Maximum="100"
Minimum="0"
StepFrequency="1"
Value="{x:Bind ViewModel.Appearance.BackgroundImageTintIntensity, Mode=TwoWay}" />
</controls:SettingsCard>
<!-- Reset background image properties -->
<controls:SettingsCard x:Uid="Settings_GeneralPage_BackgroundImage_ResetProperties_SettingsCard" Visibility="{x:Bind ViewModel.Appearance.IsBackgroundControlsVisible, Mode=OneWay}">
<!-- Reset appearance properties -->
<controls:SettingsCard x:Uid="Settings_GeneralPage_BackgroundImage_ResetProperties_SettingsCard" Visibility="{x:Bind ViewModel.Appearance.IsResetButtonVisible, Mode=OneWay}">
<StackPanel Orientation="Horizontal" Spacing="8">
<Button x:Uid="Settings_GeneralPage_Background_ResetImagePropertiesButton" Command="{x:Bind ViewModel.Appearance.ResetBackgroundImagePropertiesCommand}" />
</StackPanel>

View File

@@ -3,8 +3,13 @@
// See the LICENSE file in the project root for more information.
using System.Diagnostics;
using CommunityToolkit.Mvvm.Messaging;
using ManagedCommon;
using Microsoft.CmdPal.Core.ViewModels.Messages;
using Microsoft.CmdPal.UI.Events;
using Microsoft.CmdPal.UI.Messages;
using Microsoft.CmdPal.UI.ViewModels;
using Microsoft.CmdPal.UI.ViewModels.Messages;
using Microsoft.CmdPal.UI.ViewModels.Services;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.UI;
@@ -12,6 +17,7 @@ using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Documents;
using Microsoft.Windows.Storage.Pickers;
using Windows.Win32.Foundation;
namespace Microsoft.CmdPal.UI.Settings;
@@ -86,4 +92,9 @@ public sealed partial class AppearancePage : Page
}
});
}
private void OpenCommandPalette_Click(object sender, RoutedEventArgs e)
{
WeakReferenceMessenger.Default.Send<HotkeySummonMessage>(new(string.Empty, HWND.Null));
}
}

View File

@@ -1,17 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
@@ -26,36 +26,36 @@
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
@@ -577,6 +577,9 @@ Right-click to remove the key combination, thereby deactivating the shortcut.</v
<data name="Settings_GeneralPage_BackgroundTintIntensity_SettingsCard.Header" xml:space="preserve">
<value>Color intensity</value>
</data>
<data name="Settings_GeneralPage_ImageTintIntensity_SettingsCard.Header" xml:space="preserve">
<value>Color intensity</value>
</data>
<data name="OptionalColorPickerButton_UnsetTextBlock.Text" xml:space="preserve">
<value>Choose color</value>
</data>
@@ -668,7 +671,7 @@ Right-click to remove the key combination, thereby deactivating the shortcut.</v
<value>Background image</value>
</data>
<data name="Settings_GeneralPage_NoBackground_DescriptionTextBlock.Text" xml:space="preserve">
<value>No settings</value>
<value>No additional settings are available.</value>
</data>
<data name="Settings_GeneralPage_Background_SettingsExpander.Header" xml:space="preserve">
<value>Background</value>
@@ -676,6 +679,9 @@ Right-click to remove the key combination, thereby deactivating the shortcut.</v
<data name="Settings_GeneralPage_Background_SettingsExpander.Description" xml:space="preserve">
<value>Choose a custom background color or image</value>
</data>
<data name="Settings_GeneralPage_Background_NotAvailable.Text" xml:space="preserve">
<value>Not available with Mica</value>
</data>
<data name="Settings_GeneralPage_WindowsAccentColor_SettingsCard.Header" xml:space="preserve">
<value>System accent color</value>
</data>
@@ -692,7 +698,7 @@ Right-click to remove the key combination, thereby deactivating the shortcut.</v
<value>Restore defaults</value>
</data>
<data name="Settings_GeneralPage_Background_ResetImagePropertiesButton.Content" xml:space="preserve">
<value>Reset</value>
<value>Reset image settings</value>
</data>
<data name="Settings_GeneralPage_WindowsAccentColor_SettingsCard_Description1.Text" xml:space="preserve">
<value>Change the system accent in Windows Settings:</value>
@@ -727,4 +733,45 @@ Right-click to remove the key combination, thereby deactivating the shortcut.</v
<data name="Settings_GeneralPage_VersionNo" xml:space="preserve">
<value>Version {0}</value>
</data>
<data name="Settings_GeneralPage_BackdropOpacity_SettingsCard.Header" xml:space="preserve">
<value>Opacity</value>
</data>
<data name="Settings_GeneralPage_BackdropStyle_SettingsCard.Header" xml:space="preserve">
<value>Material</value>
</data>
<data name="Settings_GeneralPage_BackdropStyle_SettingsCard.Description" xml:space="preserve">
<value>Select the visual material used for the window background</value>
</data>
<data name="Settings_GeneralPage_BackdropStyle_Acrylic.Content" xml:space="preserve">
<value>Acrylic (default)</value>
</data>
<data name="Settings_GeneralPage_BackdropStyle_Transparent.Content" xml:space="preserve">
<value>Transparent</value>
</data>
<data name="Settings_GeneralPage_BackdropStyle_Mica.Content" xml:space="preserve">
<value>Mica</value>
</data>
<data name="Settings_GeneralPage_BackdropStyle_AcrylicThin.Content" xml:space="preserve">
<value>Thin Acrylic</value>
</data>
<data name="Settings_GeneralPage_BackdropStyle_MicaAlt.Content" xml:space="preserve">
<value>Mica Alt</value>
</data>
<data name="Settings_GeneralPage_MicaBackdrop_DescriptionTextBlock.Text" xml:space="preserve">
<value>Mica automatically adapts to your desktop wallpaper. Custom backgrounds and opacity settings are not available for this material.</value>
</data>
<data name="Settings_AppearancePage_OpenCommandPaletteButton.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Open Command Palette</value>
<comment>Button to open the Command Palette window to preview appearance changes</comment>
</data>
<data name="Settings_AppearancePage_OpenCommandPaletteButton_Text.Text" xml:space="preserve">
<value>Open Command Palette</value>
</data>
<data name="Settings_AppearancePage_ResetAppearanceButton.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Reset appearance settings</value>
<comment>Button to reset all appearance settings to their default values</comment>
</data>
<data name="Settings_AppearancePage_ResetAppearanceButton_Text.Text" xml:space="preserve">
<value>Reset to defaults</value>
</data>
</root>