Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
33 changes: 30 additions & 3 deletions src/UniGetUI.Avalonia/Infrastructure/MicaWindowHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Avalonia.Controls.Primitives;
using Avalonia.Media;
using Avalonia.Platform;
using UniGetUI.Avalonia.Assets.Styles;

namespace UniGetUI.Avalonia.Infrastructure;

Expand All @@ -24,6 +25,7 @@ internal static class MicaWindowHelper
private const int DWMSBT_TRANSIENTWINDOW = 3; // Acrylic — for transient surfaces (menus/flyouts); Mica won't paint on these

private static bool _acrylicPopupsHooked;
private static bool _micaConfirmedUnavailable;

public static void Apply(Window window)
{
Expand Down Expand Up @@ -71,6 +73,9 @@ public static void EnableAcrylicPopups()

private static void ApplyAcrylicToPopup(TopLevel root)
{
if (!IsMicaEnabled())
return;

// Request acrylic (not Transparent): the Transparent level makes a layered window, and DWM
// system backdrops never paint on those — so the popup ended up fully see-through with only
// the presenter tint, unreadable when shown over the desktop (e.g. the tray menu). AcrylicBlur
Expand All @@ -89,15 +94,37 @@ private static void ApplyAcrylicToPopup(TopLevel root)
}

/// <summary>
/// True when the native Mica look should be used: Windows 11+ AND the user has
/// "Transparency effects" enabled. When transparency is off we keep the solid look,
/// since the Mica backdrop otherwise lingers (DWM keeps painting it).
/// True when the native Mica look should be used: Windows 11+, "Transparency effects" on,
/// GPU-accelerated (software rendering can't be transparent, so Mica shows as black — #5111),
/// and no window has since found the backdrop didn't engage. Otherwise keep the solid look.
/// </summary>
public static bool IsMicaEnabled()
=> OperatingSystem.IsWindows()
&& Environment.OSVersion.Version.Build >= 22000
&& !_micaConfirmedUnavailable
&& !WindowsAvaloniaRenderingPolicy.ShouldUseSoftwareRendering
&& IsOsTransparencyEnabled();

/// <summary>
/// Latch Mica off for the session and drop the translucent surface overrides so every surface
/// falls back to the solid look, once a window confirms the backdrop never engaged (#5111).
/// </summary>
public static void NotifyMicaUnavailable()
{
if (_micaConfirmedUnavailable)
return;
_micaConfirmedUnavailable = true;

if (Application.Current is { } app)
{
for (int i = app.Resources.MergedDictionaries.Count - 1; i >= 0; i--)
{
if (app.Resources.MergedDictionaries[i] is WindowsMicaStyles)
app.Resources.MergedDictionaries.RemoveAt(i);
}
}
}

private static bool IsOsTransparencyEnabled()
{
if (!OperatingSystem.IsWindows())
Expand Down
10 changes: 10 additions & 0 deletions src/UniGetUI.Avalonia/Views/MainWindow.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -851,6 +851,16 @@ private void SetupMicaAndAccentBorder()
return;
}

// Mica was requested; None means DWM granted no backdrop, so the transparent window would
// render pure black (#5111). Latch Mica off and keep a solid background instead.
if (ActualTransparencyLevel == WindowTransparencyLevel.None)
{
MicaWindowHelper.NotifyMicaUnavailable();
if (this.TryFindResource("AppWindowBackground", ActualThemeVariant, out var solidBg) && solidBg is IBrush solidBrush)
Background = solidBrush;
return;
}

// The custom NCCALCSIZE frame keeps WS_THICKFRAME, so DWM still has a frame to round.
int corner = DWMWCP_ROUND;
NativeMethods.DwmSetWindowAttribute(handle, DWMWA_WINDOW_CORNER_PREFERENCE, ref corner, sizeof(int));
Expand Down
Loading