From c2f449e94e44433b99a61f9e611aaa0ddcdbef0d Mon Sep 17 00:00:00 2001 From: GabrielDuf Date: Fri, 17 Jul 2026 10:23:15 -0400 Subject: [PATCH] Fix dark theme rendering as pure black when Mica can't paint --- .../Infrastructure/MicaWindowHelper.cs | 33 +++++++++++++++++-- .../Views/MainWindow.axaml.cs | 10 ++++++ 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/UniGetUI.Avalonia/Infrastructure/MicaWindowHelper.cs b/src/UniGetUI.Avalonia/Infrastructure/MicaWindowHelper.cs index beab6ec6f7..17b65453a5 100644 --- a/src/UniGetUI.Avalonia/Infrastructure/MicaWindowHelper.cs +++ b/src/UniGetUI.Avalonia/Infrastructure/MicaWindowHelper.cs @@ -5,6 +5,7 @@ using Avalonia.Controls.Primitives; using Avalonia.Media; using Avalonia.Platform; +using UniGetUI.Avalonia.Assets.Styles; namespace UniGetUI.Avalonia.Infrastructure; @@ -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) { @@ -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 @@ -89,15 +94,37 @@ private static void ApplyAcrylicToPopup(TopLevel root) } /// - /// 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. /// public static bool IsMicaEnabled() => OperatingSystem.IsWindows() && Environment.OSVersion.Version.Build >= 22000 + && !_micaConfirmedUnavailable + && !WindowsAvaloniaRenderingPolicy.ShouldUseSoftwareRendering && IsOsTransparencyEnabled(); + /// + /// 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). + /// + 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()) diff --git a/src/UniGetUI.Avalonia/Views/MainWindow.axaml.cs b/src/UniGetUI.Avalonia/Views/MainWindow.axaml.cs index de72d4e182..9591e0564c 100644 --- a/src/UniGetUI.Avalonia/Views/MainWindow.axaml.cs +++ b/src/UniGetUI.Avalonia/Views/MainWindow.axaml.cs @@ -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));