From 98ec2ce4acabc8fef40bb9415ca58f41c4cf3de0 Mon Sep 17 00:00:00 2001 From: ema Date: Fri, 3 Apr 2026 00:31:19 +0800 Subject: [PATCH] Add Acrylic and Tabbed backdrop --- QuickLook.Common/Helpers/WindowHelper.cs | 19 ++- QuickLook.Common/NativeMethods/Dwmapi.cs | 9 +- QuickLook/ViewerWindow.xaml.cs | 145 ++++++++++++++++++++--- 3 files changed, 149 insertions(+), 24 deletions(-) diff --git a/QuickLook.Common/Helpers/WindowHelper.cs b/QuickLook.Common/Helpers/WindowHelper.cs index 981ab30..759e336 100644 --- a/QuickLook.Common/Helpers/WindowHelper.cs +++ b/QuickLook.Common/Helpers/WindowHelper.cs @@ -168,7 +168,7 @@ public static class WindowHelper Marshal.FreeHGlobal(accentPtr); } - public static void DisableBlur(Window window) + public static void DisableDwmBlur(Window window) { var accent = new AccentPolicy(); var accentStructSize = Marshal.SizeOf(accent); @@ -211,6 +211,11 @@ public static class WindowHelper var hwnd = new WindowInteropHelper(window).Handle; + if (!window.AllowsTransparency && HwndSource.FromHwnd(hwnd) is HwndSource hwndSource) + { + hwndSource.CompositionTarget.BackgroundColor = Colors.Transparent; + } + var isDarkThemeInt = isDarkTheme ? 1 : 0; Dwmapi.DwmSetWindowAttribute(hwnd, (uint)Dwmapi.WindowAttribute.UseImmersiveDarkMode, ref isDarkThemeInt, Marshal.SizeOf(typeof(bool))); @@ -228,7 +233,17 @@ public static class WindowHelper public static void EnableBackdropMicaBlur(Window window, bool isDarkTheme) { - EnableDwmBlur(window, isDarkTheme, (uint)Dwmapi.WindowAttribute.SystembackdropType, (int)Dwmapi.SystembackdropType.MainWindow); + EnableDwmBlur(window, isDarkTheme, (uint)Dwmapi.WindowAttribute.SystembackdropType, (int)Dwmapi.SystembackdropType.Mica); + } + + public static void EnableBackdropAcrylicBlur(Window window, bool isDarkTheme) + { + EnableDwmBlur(window, isDarkTheme, (uint)Dwmapi.WindowAttribute.SystembackdropType, (int)Dwmapi.SystembackdropType.Acrylic); + } + + public static void EnableBackdropTabbedBlur(Window window, bool isDarkTheme) + { + EnableDwmBlur(window, isDarkTheme, (uint)Dwmapi.WindowAttribute.SystembackdropType, (int)Dwmapi.SystembackdropType.Tabbed); } [StructLayout(LayoutKind.Sequential)] diff --git a/QuickLook.Common/NativeMethods/Dwmapi.cs b/QuickLook.Common/NativeMethods/Dwmapi.cs index 99c1435..1c5e7b3 100644 --- a/QuickLook.Common/NativeMethods/Dwmapi.cs +++ b/QuickLook.Common/NativeMethods/Dwmapi.cs @@ -41,9 +41,12 @@ public static class Dwmapi { Auto = 0, None = 1, - MainWindow = 2, - TransientWindow = 3, - TabbedWindow = 4, + Mica = 2, + Acrylic = 3, // Automatically selects the best Acrylic effect available on the system (Acrylic11 > Acrylic10) + Tabbed = 4, + + Acrylic10, // Windows 10 style, supported on Windows 10 and 11 + Acrylic11, // Windows 11 style, supported on Windows 11 22523+ (Insider) and 22621+ (Stable) } [DllImport("DwmApi.dll")] diff --git a/QuickLook/ViewerWindow.xaml.cs b/QuickLook/ViewerWindow.xaml.cs index f14d076..bb6ff76 100644 --- a/QuickLook/ViewerWindow.xaml.cs +++ b/QuickLook/ViewerWindow.xaml.cs @@ -27,6 +27,7 @@ using System.Windows.Input; using System.Windows.Media.Animation; using System.Windows.Shell; using Wpf.Ui.Violeta.Controls; +using static QuickLook.Common.NativeMethods.Dwmapi; using Brush = System.Windows.Media.Brush; using FontFamily = System.Windows.Media.FontFamily; using Size = System.Windows.Size; @@ -157,6 +158,12 @@ public partial class ViewerWindow : Window base.Close(); } + protected override void OnSourceInitialized(EventArgs e) + { + base.OnSourceInitialized(e); + ApplyWindowBackgroundEffects(); + } + public override void OnApplyTemplate() { base.OnApplyTemplate(); @@ -171,31 +178,14 @@ public partial class ViewerWindow : Window var useTransparency = SettingHelper.Get("UseTransparency", true) && SystemParameters.IsGlassEnabled && !App.IsGPUInBlacklist; + var backdrop = GetBackdropOption(); var windowChrome = WindowChrome.GetWindowChrome(this); windowChrome?.GlassFrameThickness = useTransparency ? new Thickness(1) : new Thickness(0); if (useTransparency) { - if (App.IsWin11) - { - if (Environment.OSVersion.Version >= new Version(10, 0, 22523)) - { - WindowHelper.EnableBackdropMicaBlur(this, CurrentTheme == Themes.Dark); - } - else - { - WindowHelper.EnableMicaBlur(this, CurrentTheme == Themes.Dark); - } - } - else if (App.IsWin10) - { - WindowHelper.EnableBlur(this); - } - else - { - Background = (Brush)FindResource("MainWindowBackgroundNoTransparent"); - } + ApplyBackdrop(backdrop); } else { @@ -216,6 +206,123 @@ public partial class ViewerWindow : Window } } + private void ApplyBackdrop(SystembackdropType backdrop) + { + switch (backdrop) + { + case SystembackdropType.None: + Background = (Brush)FindResource("MainWindowBackgroundNoTransparent"); + break; + + case SystembackdropType.Mica: + if (App.IsWin11) + { + if (Environment.OSVersion.Version >= new Version(10, 0, 22523)) + { + WindowHelper.DisableDwmBlur(this); + WindowHelper.EnableBackdropMicaBlur(this, CurrentTheme == Themes.Dark); + } + else + { + WindowHelper.DisableDwmBlur(this); + WindowHelper.EnableMicaBlur(this, CurrentTheme == Themes.Dark); + } + } + else if (App.IsWin10) + { + WindowHelper.DisableDwmBlur(this); + WindowHelper.EnableBlur(this); + } + else + { + Background = (Brush)FindResource("MainWindowBackgroundNoTransparent"); + } + + break; + + case SystembackdropType.Acrylic: + if (App.IsWin11 && Environment.OSVersion.Version >= new Version(10, 0, 22523)) + { + WindowHelper.DisableDwmBlur(this); + WindowHelper.EnableBackdropAcrylicBlur(this, CurrentTheme == Themes.Dark); + } + else if (App.IsWin10) + { + WindowHelper.DisableDwmBlur(this); + WindowHelper.EnableBlur(this); + } + else + { + Background = (Brush)FindResource("MainWindowBackgroundNoTransparent"); + } + + break; + + case SystembackdropType.Tabbed: + if (App.IsWin11 && Environment.OSVersion.Version >= new Version(10, 0, 22523)) + { + WindowHelper.DisableDwmBlur(this); + WindowHelper.EnableBackdropTabbedBlur(this, CurrentTheme == Themes.Dark); + } + else if (App.IsWin10) + { + WindowHelper.DisableDwmBlur(this); + WindowHelper.EnableBlur(this); + } + else + { + Background = (Brush)FindResource("MainWindowBackgroundNoTransparent"); + } + + break; + + case SystembackdropType.Auto: + default: + if (App.IsWin11) + { + if (Environment.OSVersion.Version >= new Version(10, 0, 22523)) + { + WindowHelper.DisableDwmBlur(this); + WindowHelper.EnableBackdropMicaBlur(this, CurrentTheme == Themes.Dark); + } + else + { + WindowHelper.DisableDwmBlur(this); + WindowHelper.EnableMicaBlur(this, CurrentTheme == Themes.Dark); + } + } + else if (App.IsWin10) + { + WindowHelper.DisableDwmBlur(this); + WindowHelper.EnableBlur(this); + } + else + { + Background = (Brush)FindResource("MainWindowBackgroundNoTransparent"); + } + + break; + } + } + + private static SystembackdropType GetBackdropOption() + { + var option = SettingHelper.Get("WindowBackdrop", nameof(SystembackdropType.Auto), "QuickLook")?.Trim(); + + if (string.IsNullOrEmpty(option)) + return SystembackdropType.Auto; + + if (string.Equals(option, nameof(SystembackdropType.Acrylic), StringComparison.OrdinalIgnoreCase)) + return SystembackdropType.Acrylic; + + if (string.Equals(option, nameof(SystembackdropType.Tabbed), StringComparison.OrdinalIgnoreCase)) + return SystembackdropType.Tabbed; + + return Enum.TryParse(option, true, out SystembackdropType parsed) + ? parsed + : SystembackdropType.Auto; + } + private void SaveWindowSizeOnSizeChanged(object sender, SizeChangedEventArgs e) { // first shown?