Skip to content

Align Acrylic10 tint behavior with official dark/light acrylic palette - #1915

Merged
emako merged 4 commits into
masterfrom
copilot/update-acrylic-color-schemes
Apr 14, 2026
Merged

Align Acrylic10 tint behavior with official dark/light acrylic palette#1915
emako merged 4 commits into
masterfrom
copilot/update-acrylic-color-schemes

Conversation

Copilot AI commented Apr 14, 2026

Copy link
Copy Markdown
Contributor

Acrylic10 in QuickLook did not match the issue’s target visual parameters for dark/light mode. This change aligns Acrylic10 tint color and tint opacity with the specified official values while keeping non-Acrylic10 backdrop behavior unchanged.

  • Acrylic10 tint now follows official dark/light values

    • Added Acrylic10-specific theme palette in ViewerWindow:
      • Dark: #171717
      • Light: #F2F2F2
    • SystembackdropType.Acrylic10 now uses this palette via GetAcrylic10TintColor().
  • Acrylic10 tint opacity set to 0.70

    • Extended WindowHelper.EnableAcrylicBlur(...) with an optional tintOpacity parameter (default remains 0.8 to preserve existing callers).
    • Acrylic10 now calls EnableAcrylicBlur(..., tintOpacity: 0.7).
  • No functional drift for other backdrop modes

    • Existing Acrylic/Acrylic11/Mica/Tabbed code paths continue using prior defaults and behavior.
    • Custom WindowBackgroundColor override remains supported and still takes precedence when valid.
case SystembackdropType.Acrylic10:
{
    var acrylicTint = GetAcrylic10TintColor();
    WindowHelper.EnableAcrylicBlur(this, acrylicTint, CurrentTheme == Themes.Dark, Acrylic10TintOpacity);
    break;
}

private Color GetAcrylic10TintColor() =>
    CurrentTheme == Themes.Dark ? Color.FromRgb(0x17, 0x17, 0x17) : Color.FromRgb(0xF2, 0xF2, 0xF2);

Summary by Sourcery

Align Acrylic10 backdrop appearance with the official dark/light acrylic palette while preserving existing behavior for other backdrops.

New Features:

  • Introduce dedicated Acrylic10 dark and light tint colors based on the current theme.
  • Allow configuring acrylic blur tint opacity via an optional parameter in the window helper.

Enhancements:

  • Use a specific Acrylic10 tint color selector that respects custom window background color when valid and falls back to theme-specific defaults.
  • Constrain color conversion error handling to expected format and support exceptions instead of swallowing all exceptions in background color parsing.

Copilot AI linked an issue Apr 14, 2026 that may be closed by this pull request
Copilot AI changed the title [WIP] Update official acrylic color schemes for dark and light modes Align Acrylic10 tint behavior with official dark/light acrylic palette Apr 14, 2026
Copilot AI requested a review from emako April 14, 2026 10:08
@emako
emako marked this pull request as ready for review April 14, 2026 16:24
Copilot AI review requested due to automatic review settings April 14, 2026 16:24
@emako
emako merged commit 2229c16 into master Apr 14, 2026
@sourcery-ai

sourcery-ai Bot commented Apr 14, 2026

Copy link
Copy Markdown

Reviewer's Guide

Aligns the Acrylic10 backdrop’s tint color and opacity with official dark/light acrylic palette values while preserving existing behavior for other backdrop modes and maintaining custom background overrides.

Sequence diagram for Acrylic10 backdrop application with new tint palette and opacity

sequenceDiagram
    participant VW as ViewerWindow
    participant SH as SettingHelper
    participant WH as WindowHelper

    VW->>VW: ApplyBackdrop(backdrop)
    alt backdrop is Acrylic10 and OS is Win10 or Win11
        VW->>VW: GetAcrylic10TintColor()
        VW->>SH: Get(WindowBackgroundColor)
        alt custom color present and valid
            VW-->>VW: use custom color as acrylicTint
        else custom color missing or invalid
            VW-->>VW: use Acrylic10DarkTintColor or Acrylic10LightTintColor based on CurrentTheme
        end
        VW->>WH: EnableAcrylicBlur(this, acrylicTint, isDarkTheme, Acrylic10TintOpacity)
        VW-->>VW: Background = Transparent
    else other backdrop types
        VW-->>VW: use existing backdrop logic
    end
Loading

Class diagram for updated ViewerWindow and WindowHelper acrylic handling

classDiagram
    class ViewerWindow {
        - double Acrylic10TintOpacity
        - Color Acrylic10DarkTintColor
        - Color Acrylic10LightTintColor
        - Size _customWindowSize
        - bool _ignoreNextWindowSizeChange
        - string _path
        - Themes CurrentTheme
        + void ApplyBackdrop(SystembackdropType backdrop)
        - Color GetAcrylicTintColor()
        - Color GetAcrylic10TintColor()
        - void ApplyWindowBackgroundEffects()
    }

    class WindowHelper {
        + static void EnableBlur(Window window)
        + static void EnableAcrylicBlur(Window window, Color tintColor, bool isDarkTheme, double tintOpacity)
        + static void DisableDwmBlur(Window window)
    }

    class SystembackdropType {
        <<enum>>
        Auto
        None
        Mica
        Acrylic
        Acrylic10
        Acrylic11
        Tabbed
    }

    class Themes {
        <<enum>>
        Light
        Dark
    }

    ViewerWindow --> WindowHelper : uses
    ViewerWindow ..> SystembackdropType : selects
    ViewerWindow ..> Themes : reads
Loading

File-Level Changes

Change Details Files
Introduce Acrylic10-specific tint palette and opacity while preserving custom window background overrides.
  • Add Acrylic10-specific tint opacity constant and dark/light tint color constants on ViewerWindow.
  • Implement GetAcrylic10TintColor that prefers user-configured WindowBackgroundColor and otherwise selects the new dark/light tints based on CurrentTheme.
  • Switch the Acrylic10 backdrop path to use GetAcrylic10TintColor and pass the new opacity constant to the blur helper.
  • Keep other backdrop modes and the existing GetAcrylicTintColor behavior unchanged.
QuickLook/ViewerWindow.xaml.cs
Extend acrylic blur helper to support configurable tint opacity without breaking existing callers.
  • Add an optional tintOpacity parameter (default 0.8) to EnableAcrylicBlur, preserving existing call sites’ behavior.
  • Use tintOpacity when computing the AccentPolicy.GradientColor instead of a hard-coded 0.8 value.
QuickLook.Common/Helpers/WindowHelper.cs
Narrow exception handling when parsing custom window background colors.
  • Update color parsing try/catch blocks to only catch FormatException and NotSupportedException, avoiding broad exception swallowing while still ignoring invalid color values.
QuickLook/ViewerWindow.xaml.cs

Assessment against linked issues

Issue Objective Addressed Explanation
#1912 Use the official acrylic tint colors for Acrylic10: #171717 in dark mode and #F2F2F2 in light mode.
#1912 Set Acrylic10 tint opacity to 0.70 to match the official acrylic parameters in both dark and light modes.

Possibly linked issues

  • #(unprovided): PR implements the issue’s official dark/light acrylic palette (#171717/#F2F2F2, opacity 0.70) for Acrylic10 windows.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • The custom color retrieval and parsing logic in GetAcrylicTintColor() and GetAcrylic10TintColor() is duplicated; consider extracting a shared helper (e.g., TryGetCustomWindowBackgroundColor()) so future changes to this behavior stay consistent in one place.
  • In WindowHelper.EnableAcrylicBlur, you might want to clamp or validate the tintOpacity parameter to the expected 0–1 range so that accidental out-of-range values do not lead to unexpected visual behavior.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The custom color retrieval and parsing logic in `GetAcrylicTintColor()` and `GetAcrylic10TintColor()` is duplicated; consider extracting a shared helper (e.g., `TryGetCustomWindowBackgroundColor()`) so future changes to this behavior stay consistent in one place.
- In `WindowHelper.EnableAcrylicBlur`, you might want to clamp or validate the `tintOpacity` parameter to the expected 0–1 range so that accidental out-of-range values do not lead to unexpected visual behavior.

## Individual Comments

### Comment 1
<location path="QuickLook.Common/Helpers/WindowHelper.cs" line_range="171-174" />
<code_context>
         Marshal.FreeHGlobal(accentPtr);
     }

-    public static void EnableAcrylicBlur(Window window, Color tintColor, bool isDarkTheme)
+    public static void EnableAcrylicBlur(Window window, Color tintColor, bool isDarkTheme, double tintOpacity = 0.8)
     {
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Consider validating or clamping the `tintOpacity` parameter before passing it to `ToAbgr`.

Since `tintOpacity` is now a public parameter, callers can pass values outside the expected [0, 1] range. If `ToAbgr` assumes a normalized value, consider clamping or validating `tintOpacity` in `EnableAcrylicBlur` (and falling back to the default) to avoid invalid alpha values or unexpected visuals for inputs like -0.1 or 1.5.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines -171 to 174
public static void EnableAcrylicBlur(Window window, Color tintColor, bool isDarkTheme)
public static void EnableAcrylicBlur(Window window, Color tintColor, bool isDarkTheme, double tintOpacity = 0.8)
{
window.Background = Brushes.Transparent;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): Consider validating or clamping the tintOpacity parameter before passing it to ToAbgr.

Since tintOpacity is now a public parameter, callers can pass values outside the expected [0, 1] range. If ToAbgr assumes a normalized value, consider clamping or validating tintOpacity in EnableAcrylicBlur (and falling back to the default) to avoid invalid alpha values or unexpected visuals for inputs like -0.1 or 1.5.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Aligns the Win10 Acrylic (“Acrylic10”) backdrop tint and opacity with the specified dark/light palette values while keeping other backdrop modes’ behavior unchanged.

Changes:

  • Adds Acrylic10-specific tint colors (dark/light) and uses them when no custom WindowBackgroundColor override is provided.
  • Introduces an optional tintOpacity parameter to WindowHelper.EnableAcrylicBlur(...) and uses 0.7 specifically for Acrylic10.
  • Narrows invalid color parsing catches to specific exception types (via exception filters).

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.

File Description
QuickLook/ViewerWindow.xaml.cs Adds Acrylic10 tint palette + opacity constant and routes Acrylic10 through a dedicated tint-color resolver.
QuickLook.Common/Helpers/WindowHelper.cs Extends EnableAcrylicBlur to accept a tint opacity and applies it when building the ABGR gradient color.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 195 to 197
accent.AccentState = AccentState.AccentEnableAcrylicblurbehind;
accent.GradientColor = ToAbgr(tintColor, 0.8);
accent.GradientColor = ToAbgr(tintColor, tintOpacity);

Copilot AI Apr 14, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new tintOpacity parameter is used directly in ToAbgr(tintColor, tintOpacity) without validation. Values outside [0,1] can overflow/truncate the alpha channel during the << 24 shift in ToAbgr, producing incorrect gradient colors. Consider clamping tintOpacity to [0, 1] (or clamping the computed alpha to byte range) before calling ToAbgr.

Copilot uses AI. Check for mistakes.
Comment on lines +211 to 214
catch (Exception ex) when (ex is FormatException || ex is NotSupportedException)
{
// Ignore invalid color
}

Copilot AI Apr 14, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This catch (Exception ex) when (...) declares ex but never uses it. To avoid unused-variable analyzer warnings and keep the intent clearer, consider either catch (Exception) when (...) or catching FormatException / NotSupportedException explicitly.

Suggested change
catch (Exception ex) when (ex is FormatException || ex is NotSupportedException)
{
// Ignore invalid color
}
catch (FormatException)
{
// Ignore invalid color
}
catch (NotSupportedException)
{
// Ignore invalid color
}

Copilot uses AI. Check for mistakes.
Comment on lines +363 to 364
catch (Exception ex) when (ex is FormatException || ex is NotSupportedException)
{

Copilot AI Apr 14, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This catch (Exception ex) when (...) declares ex but never uses it. To avoid unused-variable analyzer warnings and keep the intent clearer, consider either catch (Exception) when (...) or catching FormatException / NotSupportedException explicitly.

Copilot uses AI. Check for mistakes.
Comment on lines +382 to +383
catch (Exception ex) when (ex is FormatException || ex is NotSupportedException)
{

Copilot AI Apr 14, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This catch (Exception ex) when (...) declares ex but never uses it. To avoid unused-variable analyzer warnings and keep the intent clearer, consider either catch (Exception) when (...) or catching FormatException / NotSupportedException explicitly.

Copilot uses AI. Check for mistakes.
Comment on lines +372 to +386
private Color GetAcrylic10TintColor()
{
var customColor = SettingHelper.Get("WindowBackgroundColor", string.Empty, "QuickLook");

if (!string.IsNullOrEmpty(customColor))
{
try
{
return ((SolidColorBrush)new BrushConverter().ConvertFromString(customColor)).Color;
}
catch (Exception ex) when (ex is FormatException || ex is NotSupportedException)
{
// Ignore invalid color
}
}

Copilot AI Apr 14, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GetAcrylic10TintColor() duplicates the custom color override parsing logic from GetAcrylicTintColor(). Since both read the same setting and have identical parsing/exception handling, consider factoring this into a shared helper (e.g., a method that tries to parse WindowBackgroundColor and returns a nullable Color) to avoid future divergence between the two code paths.

Copilot uses AI. Check for mistakes.
Comment on lines +171 to 172
public static void EnableAcrylicBlur(Window window, Color tintColor, bool isDarkTheme, double tintOpacity = 0.8)
{

Copilot AI Apr 14, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WindowHelper.EnableAcrylicBlur is a public method in QuickLook.Common; changing its signature by adding a parameter is a binary breaking change for any existing plugins/binaries compiled against the old 3-arg method. To preserve backward compatibility, keep the original overload EnableAcrylicBlur(Window, Color, bool) and have it call the new overload with the default opacity (0.8).

Suggested change
public static void EnableAcrylicBlur(Window window, Color tintColor, bool isDarkTheme, double tintOpacity = 0.8)
{
public static void EnableAcrylicBlur(Window window, Color tintColor, bool isDarkTheme)
{
EnableAcrylicBlur(window, tintColor, isDarkTheme, 0.8);
}
public static void EnableAcrylicBlur(Window window, Color tintColor, bool isDarkTheme, double tintOpacity)
{

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Official acrylic color schemes in dark/light modes

3 participants