Skip to content

Commit b22bb3a

Browse files
committed
Add acrylic blur & DWM caption color support
1 parent 94b56a8 commit b22bb3a

3 files changed

Lines changed: 124 additions & 8 deletions

File tree

‎QuickLook.Common/Helpers/WindowHelper.cs‎

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,40 @@ public static void EnableBlur(Window window)
168168
Marshal.FreeHGlobal(accentPtr);
169169
}
170170

171+
public static void EnableAcrylicBlur(Window window, Color tintColor)
172+
{
173+
window.Background = Brushes.Transparent;
174+
175+
var hwnd = new WindowInteropHelper(window).EnsureHandle();
176+
177+
if (!window.AllowsTransparency && HwndSource.FromHwnd(hwnd) is HwndSource hwndSource)
178+
{
179+
hwndSource.CompositionTarget.BackgroundColor = Colors.Transparent;
180+
}
181+
182+
var margins = new Dwmapi.Margins(-1, -1, -1, -1);
183+
Dwmapi.DwmExtendFrameIntoClientArea(hwnd, ref margins);
184+
185+
var accent = new AccentPolicy();
186+
var accentStructSize = Marshal.SizeOf(accent);
187+
accent.AccentState = AccentState.AccentEnableAcrylicblurbehind;
188+
accent.GradientColor = ToAbgr(tintColor, 0.8);
189+
190+
var accentPtr = Marshal.AllocHGlobal(accentStructSize);
191+
Marshal.StructureToPtr(accent, accentPtr, false);
192+
193+
var data = new WindowCompositionAttributeData
194+
{
195+
Attribute = WindowCompositionAttribute.WcaAccentPolicy,
196+
SizeOfData = accentStructSize,
197+
Data = accentPtr
198+
};
199+
200+
User32.SetWindowCompositionAttribute(hwnd, ref data);
201+
202+
Marshal.FreeHGlobal(accentPtr);
203+
}
204+
171205
public static void DisableDwmBlur(Window window)
172206
{
173207
var accent = new AccentPolicy();
@@ -202,22 +236,34 @@ public static void DisableDwmBlur(Window window)
202236
var micaEnabled = 0;
203237
Dwmapi.DwmSetWindowAttribute(hwnd, (uint)Dwmapi.WindowAttribute.MicaEffect, ref micaEnabled, Marshal.SizeOf(typeof(int)));
204238
}
239+
240+
if (Environment.OSVersion.Version >= new Version(10, 0, 22000))
241+
{
242+
var captionColor = -1;
243+
Dwmapi.DwmSetWindowAttribute(hwnd, (uint)Dwmapi.WindowAttribute.CaptionColor, ref captionColor, Marshal.SizeOf(typeof(int)));
244+
}
205245
}
206246

207247
private static void EnableDwmBlur(Window window, bool isDarkTheme, uint dwAttribute, int pvAttribute)
208248
{
209249
// Mica will handle the color
210250
window.Background = Brushes.Transparent;
211251

212-
var hwnd = new WindowInteropHelper(window).Handle;
252+
var hwnd = new WindowInteropHelper(window).EnsureHandle();
213253

214254
if (!window.AllowsTransparency && HwndSource.FromHwnd(hwnd) is HwndSource hwndSource)
215255
{
216256
hwndSource.CompositionTarget.BackgroundColor = Colors.Transparent;
217257
}
218258

259+
if (Environment.OSVersion.Version >= new Version(10, 0, 22000))
260+
{
261+
var captionColor = -2;
262+
Dwmapi.DwmSetWindowAttribute(hwnd, (uint)Dwmapi.WindowAttribute.CaptionColor, ref captionColor, Marshal.SizeOf(typeof(int)));
263+
}
264+
219265
var isDarkThemeInt = isDarkTheme ? 1 : 0;
220-
Dwmapi.DwmSetWindowAttribute(hwnd, (uint)Dwmapi.WindowAttribute.UseImmersiveDarkMode, ref isDarkThemeInt, Marshal.SizeOf(typeof(bool)));
266+
Dwmapi.DwmSetWindowAttribute(hwnd, (uint)Dwmapi.WindowAttribute.UseImmersiveDarkMode, ref isDarkThemeInt, Marshal.SizeOf(typeof(int)));
221267

222268
var margins = new Dwmapi.Margins(-1, -1, -1, -1);
223269
Dwmapi.DwmExtendFrameIntoClientArea(hwnd, ref margins);
@@ -260,7 +306,16 @@ private enum AccentState
260306
AccentEnableGradient = 1,
261307
AccentEnableTransparentgradient = 2,
262308
AccentEnableBlurbehind = 3,
263-
AccentInvalidState = 4,
309+
AccentEnableAcrylicblurbehind = 4,
310+
AccentInvalidState = 5,
311+
}
312+
313+
private static uint ToAbgr(Color color, double alphaScale)
314+
{
315+
return (uint)(color.R << 0 |
316+
color.G << 8 |
317+
color.B << 16 |
318+
(int)(color.A * alphaScale) << 24);
264319
}
265320

266321
[StructLayout(LayoutKind.Sequential)]

‎QuickLook.Common/NativeMethods/Dwmapi.cs‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public struct Margins(int cxLeftWidth, int cxRightWidth, int cyTopHeight, int cy
3333
public enum WindowAttribute
3434
{
3535
UseImmersiveDarkMode = 20,
36+
CaptionColor = 35,
3637
SystembackdropType = 38,
3738
MicaEffect = 1029,
3839
}
@@ -44,9 +45,8 @@ public enum SystembackdropType
4445
Mica = 2,
4546
Acrylic = 3, // Automatically selects the best Acrylic effect available on the system (Acrylic11 > Acrylic10)
4647
Tabbed = 4,
47-
48-
Acrylic10, // Windows 10 style, supported on Windows 10 and 11
49-
Acrylic11, // Windows 11 style, supported on Windows 11 22523+ (Insider) and 22621+ (Stable)
48+
Acrylic10 = 5, // Windows 10 style, supported on Windows 10 and 11
49+
Acrylic11 = 6, // Windows 11 style, supported on Windows 11 22523+ (Insider) and 22621+ (Stable)
5050
}
5151

5252
[DllImport("DwmApi.dll")]

‎QuickLook/ViewerWindow.xaml.cs‎

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@
2929
using Wpf.Ui.Violeta.Controls;
3030
using static QuickLook.Common.NativeMethods.Dwmapi;
3131
using Brush = System.Windows.Media.Brush;
32+
using Color = System.Windows.Media.Color;
3233
using FontFamily = System.Windows.Media.FontFamily;
34+
using SolidColorBrush = System.Windows.Media.SolidColorBrush;
3335
using Size = System.Windows.Size;
3436

3537
namespace QuickLook;
@@ -180,6 +182,7 @@ private void ApplyWindowBackgroundEffects()
180182
&& SystemParameters.IsGlassEnabled
181183
&& !App.IsGPUInBlacklist;
182184
var backdrop = GetBackdropOption();
185+
var keepsTransparentBackground = useTransparency && backdrop != SystembackdropType.None;
183186

184187
var windowChrome = WindowChrome.GetWindowChrome(this);
185188
windowChrome?.GlassFrameThickness = useTransparency ? new Thickness(1) : new Thickness(0);
@@ -194,7 +197,7 @@ private void ApplyWindowBackgroundEffects()
194197
}
195198

196199
var customColor = SettingHelper.Get("WindowBackgroundColor", string.Empty, "QuickLook");
197-
if (!string.IsNullOrEmpty(customColor))
200+
if (!keepsTransparentBackground && !string.IsNullOrEmpty(customColor))
198201
{
199202
try
200203
{
@@ -249,8 +252,45 @@ private void ApplyBackdrop(SystembackdropType backdrop)
249252
}
250253
else if (App.IsWin10)
251254
{
255+
var acrylicTint = GetAcrylicTintColor();
256+
252257
WindowHelper.DisableDwmBlur(this);
253-
WindowHelper.EnableBlur(this);
258+
WindowHelper.EnableAcrylicBlur(this, acrylicTint);
259+
}
260+
else
261+
{
262+
Background = (Brush)FindResource("MainWindowBackgroundNoTransparent");
263+
}
264+
265+
break;
266+
267+
case SystembackdropType.Acrylic10:
268+
if (App.IsWin10 || App.IsWin11)
269+
{
270+
var acrylicTint = GetAcrylicTintColor();
271+
272+
WindowHelper.DisableDwmBlur(this);
273+
WindowHelper.EnableAcrylicBlur(this, acrylicTint);
274+
}
275+
else
276+
{
277+
Background = (Brush)FindResource("MainWindowBackgroundNoTransparent");
278+
}
279+
280+
break;
281+
282+
case SystembackdropType.Acrylic11:
283+
if (App.IsWin11 && Environment.OSVersion.Version >= new Version(10, 0, 22523))
284+
{
285+
WindowHelper.DisableDwmBlur(this);
286+
WindowHelper.EnableBackdropAcrylicBlur(this, CurrentTheme == Themes.Dark);
287+
}
288+
else if (App.IsWin10 || App.IsWin11)
289+
{
290+
var acrylicTint = GetAcrylicTintColor();
291+
292+
WindowHelper.DisableDwmBlur(this);
293+
WindowHelper.EnableAcrylicBlur(this, acrylicTint);
254294
}
255295
else
256296
{
@@ -306,6 +346,27 @@ private void ApplyBackdrop(SystembackdropType backdrop)
306346
}
307347
}
308348

349+
private Color GetAcrylicTintColor()
350+
{
351+
var customColor = SettingHelper.Get("WindowBackgroundColor", string.Empty, "QuickLook");
352+
353+
if (!string.IsNullOrEmpty(customColor))
354+
{
355+
try
356+
{
357+
return ((SolidColorBrush)new System.Windows.Media.BrushConverter().ConvertFromString(customColor)).Color;
358+
}
359+
catch
360+
{
361+
// ignore invalid color
362+
}
363+
}
364+
365+
return Background is SolidColorBrush currentBrush
366+
? currentBrush.Color
367+
: ((SolidColorBrush)FindResource("MainWindowBackground")).Color;
368+
}
369+
309370
private static SystembackdropType GetBackdropOption()
310371
{
311372
var option = SettingHelper.Get("WindowBackdrop", nameof(SystembackdropType.Auto), "QuickLook")?.Trim();

0 commit comments

Comments
 (0)