mirror of
https://github.com/QL-Win/QuickLook.git
synced 2026-05-07 02:00:21 +08:00
Add acrylic blur & DWM caption color support
This commit is contained in:
@@ -168,6 +168,40 @@ public static class WindowHelper
|
||||
Marshal.FreeHGlobal(accentPtr);
|
||||
}
|
||||
|
||||
public static void EnableAcrylicBlur(Window window, Color tintColor)
|
||||
{
|
||||
window.Background = Brushes.Transparent;
|
||||
|
||||
var hwnd = new WindowInteropHelper(window).EnsureHandle();
|
||||
|
||||
if (!window.AllowsTransparency && HwndSource.FromHwnd(hwnd) is HwndSource hwndSource)
|
||||
{
|
||||
hwndSource.CompositionTarget.BackgroundColor = Colors.Transparent;
|
||||
}
|
||||
|
||||
var margins = new Dwmapi.Margins(-1, -1, -1, -1);
|
||||
Dwmapi.DwmExtendFrameIntoClientArea(hwnd, ref margins);
|
||||
|
||||
var accent = new AccentPolicy();
|
||||
var accentStructSize = Marshal.SizeOf(accent);
|
||||
accent.AccentState = AccentState.AccentEnableAcrylicblurbehind;
|
||||
accent.GradientColor = ToAbgr(tintColor, 0.8);
|
||||
|
||||
var accentPtr = Marshal.AllocHGlobal(accentStructSize);
|
||||
Marshal.StructureToPtr(accent, accentPtr, false);
|
||||
|
||||
var data = new WindowCompositionAttributeData
|
||||
{
|
||||
Attribute = WindowCompositionAttribute.WcaAccentPolicy,
|
||||
SizeOfData = accentStructSize,
|
||||
Data = accentPtr
|
||||
};
|
||||
|
||||
User32.SetWindowCompositionAttribute(hwnd, ref data);
|
||||
|
||||
Marshal.FreeHGlobal(accentPtr);
|
||||
}
|
||||
|
||||
public static void DisableDwmBlur(Window window)
|
||||
{
|
||||
var accent = new AccentPolicy();
|
||||
@@ -202,6 +236,12 @@ public static class WindowHelper
|
||||
var micaEnabled = 0;
|
||||
Dwmapi.DwmSetWindowAttribute(hwnd, (uint)Dwmapi.WindowAttribute.MicaEffect, ref micaEnabled, Marshal.SizeOf(typeof(int)));
|
||||
}
|
||||
|
||||
if (Environment.OSVersion.Version >= new Version(10, 0, 22000))
|
||||
{
|
||||
var captionColor = -1;
|
||||
Dwmapi.DwmSetWindowAttribute(hwnd, (uint)Dwmapi.WindowAttribute.CaptionColor, ref captionColor, Marshal.SizeOf(typeof(int)));
|
||||
}
|
||||
}
|
||||
|
||||
private static void EnableDwmBlur(Window window, bool isDarkTheme, uint dwAttribute, int pvAttribute)
|
||||
@@ -209,15 +249,21 @@ public static class WindowHelper
|
||||
// Mica will handle the color
|
||||
window.Background = Brushes.Transparent;
|
||||
|
||||
var hwnd = new WindowInteropHelper(window).Handle;
|
||||
var hwnd = new WindowInteropHelper(window).EnsureHandle();
|
||||
|
||||
if (!window.AllowsTransparency && HwndSource.FromHwnd(hwnd) is HwndSource hwndSource)
|
||||
{
|
||||
hwndSource.CompositionTarget.BackgroundColor = Colors.Transparent;
|
||||
}
|
||||
|
||||
if (Environment.OSVersion.Version >= new Version(10, 0, 22000))
|
||||
{
|
||||
var captionColor = -2;
|
||||
Dwmapi.DwmSetWindowAttribute(hwnd, (uint)Dwmapi.WindowAttribute.CaptionColor, ref captionColor, Marshal.SizeOf(typeof(int)));
|
||||
}
|
||||
|
||||
var isDarkThemeInt = isDarkTheme ? 1 : 0;
|
||||
Dwmapi.DwmSetWindowAttribute(hwnd, (uint)Dwmapi.WindowAttribute.UseImmersiveDarkMode, ref isDarkThemeInt, Marshal.SizeOf(typeof(bool)));
|
||||
Dwmapi.DwmSetWindowAttribute(hwnd, (uint)Dwmapi.WindowAttribute.UseImmersiveDarkMode, ref isDarkThemeInt, Marshal.SizeOf(typeof(int)));
|
||||
|
||||
var margins = new Dwmapi.Margins(-1, -1, -1, -1);
|
||||
Dwmapi.DwmExtendFrameIntoClientArea(hwnd, ref margins);
|
||||
@@ -260,7 +306,16 @@ public static class WindowHelper
|
||||
AccentEnableGradient = 1,
|
||||
AccentEnableTransparentgradient = 2,
|
||||
AccentEnableBlurbehind = 3,
|
||||
AccentInvalidState = 4,
|
||||
AccentEnableAcrylicblurbehind = 4,
|
||||
AccentInvalidState = 5,
|
||||
}
|
||||
|
||||
private static uint ToAbgr(Color color, double alphaScale)
|
||||
{
|
||||
return (uint)(color.R << 0 |
|
||||
color.G << 8 |
|
||||
color.B << 16 |
|
||||
(int)(color.A * alphaScale) << 24);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
|
||||
@@ -33,6 +33,7 @@ public static class Dwmapi
|
||||
public enum WindowAttribute
|
||||
{
|
||||
UseImmersiveDarkMode = 20,
|
||||
CaptionColor = 35,
|
||||
SystembackdropType = 38,
|
||||
MicaEffect = 1029,
|
||||
}
|
||||
@@ -44,9 +45,8 @@ public static class Dwmapi
|
||||
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)
|
||||
Acrylic10 = 5, // Windows 10 style, supported on Windows 10 and 11
|
||||
Acrylic11 = 6, // Windows 11 style, supported on Windows 11 22523+ (Insider) and 22621+ (Stable)
|
||||
}
|
||||
|
||||
[DllImport("DwmApi.dll")]
|
||||
|
||||
@@ -29,7 +29,9 @@ using System.Windows.Shell;
|
||||
using Wpf.Ui.Violeta.Controls;
|
||||
using static QuickLook.Common.NativeMethods.Dwmapi;
|
||||
using Brush = System.Windows.Media.Brush;
|
||||
using Color = System.Windows.Media.Color;
|
||||
using FontFamily = System.Windows.Media.FontFamily;
|
||||
using SolidColorBrush = System.Windows.Media.SolidColorBrush;
|
||||
using Size = System.Windows.Size;
|
||||
|
||||
namespace QuickLook;
|
||||
@@ -180,6 +182,7 @@ public partial class ViewerWindow : Window
|
||||
&& SystemParameters.IsGlassEnabled
|
||||
&& !App.IsGPUInBlacklist;
|
||||
var backdrop = GetBackdropOption();
|
||||
var keepsTransparentBackground = useTransparency && backdrop != SystembackdropType.None;
|
||||
|
||||
var windowChrome = WindowChrome.GetWindowChrome(this);
|
||||
windowChrome?.GlassFrameThickness = useTransparency ? new Thickness(1) : new Thickness(0);
|
||||
@@ -194,7 +197,7 @@ public partial class ViewerWindow : Window
|
||||
}
|
||||
|
||||
var customColor = SettingHelper.Get("WindowBackgroundColor", string.Empty, "QuickLook");
|
||||
if (!string.IsNullOrEmpty(customColor))
|
||||
if (!keepsTransparentBackground && !string.IsNullOrEmpty(customColor))
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -249,8 +252,45 @@ public partial class ViewerWindow : Window
|
||||
}
|
||||
else if (App.IsWin10)
|
||||
{
|
||||
var acrylicTint = GetAcrylicTintColor();
|
||||
|
||||
WindowHelper.DisableDwmBlur(this);
|
||||
WindowHelper.EnableBlur(this);
|
||||
WindowHelper.EnableAcrylicBlur(this, acrylicTint);
|
||||
}
|
||||
else
|
||||
{
|
||||
Background = (Brush)FindResource("MainWindowBackgroundNoTransparent");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SystembackdropType.Acrylic10:
|
||||
if (App.IsWin10 || App.IsWin11)
|
||||
{
|
||||
var acrylicTint = GetAcrylicTintColor();
|
||||
|
||||
WindowHelper.DisableDwmBlur(this);
|
||||
WindowHelper.EnableAcrylicBlur(this, acrylicTint);
|
||||
}
|
||||
else
|
||||
{
|
||||
Background = (Brush)FindResource("MainWindowBackgroundNoTransparent");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SystembackdropType.Acrylic11:
|
||||
if (App.IsWin11 && Environment.OSVersion.Version >= new Version(10, 0, 22523))
|
||||
{
|
||||
WindowHelper.DisableDwmBlur(this);
|
||||
WindowHelper.EnableBackdropAcrylicBlur(this, CurrentTheme == Themes.Dark);
|
||||
}
|
||||
else if (App.IsWin10 || App.IsWin11)
|
||||
{
|
||||
var acrylicTint = GetAcrylicTintColor();
|
||||
|
||||
WindowHelper.DisableDwmBlur(this);
|
||||
WindowHelper.EnableAcrylicBlur(this, acrylicTint);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -306,6 +346,27 @@ public partial class ViewerWindow : Window
|
||||
}
|
||||
}
|
||||
|
||||
private Color GetAcrylicTintColor()
|
||||
{
|
||||
var customColor = SettingHelper.Get("WindowBackgroundColor", string.Empty, "QuickLook");
|
||||
|
||||
if (!string.IsNullOrEmpty(customColor))
|
||||
{
|
||||
try
|
||||
{
|
||||
return ((SolidColorBrush)new System.Windows.Media.BrushConverter().ConvertFromString(customColor)).Color;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignore invalid color
|
||||
}
|
||||
}
|
||||
|
||||
return Background is SolidColorBrush currentBrush
|
||||
? currentBrush.Color
|
||||
: ((SolidColorBrush)FindResource("MainWindowBackground")).Color;
|
||||
}
|
||||
|
||||
private static SystembackdropType GetBackdropOption()
|
||||
{
|
||||
var option = SettingHelper.Get("WindowBackdrop", nameof(SystembackdropType.Auto), "QuickLook")?.Trim();
|
||||
|
||||
Reference in New Issue
Block a user