From 0e9c2e428fb61953fd8f152125897646fe6fd337 Mon Sep 17 00:00:00 2001
From: Yuhang Zhao <zhaoyuhang@rankyee.com>
Date: 摹曛, 21 12月 2023 16:44:30 +0800
Subject: [PATCH] add mica mica alt acrylic

---
 src/core/contexts/win32windowcontext.cpp |  191 ++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 171 insertions(+), 20 deletions(-)

diff --git a/src/core/contexts/win32windowcontext.cpp b/src/core/contexts/win32windowcontext.cpp
index 1b969cf..76510ee 100644
--- a/src/core/contexts/win32windowcontext.cpp
+++ b/src/core/contexts/win32windowcontext.cpp
@@ -62,6 +62,82 @@
         _DWMWA_MICA_EFFECT = 1029
     };
 
+    // Types used with DWMWA_SYSTEMBACKDROP_TYPE
+    enum _DWM_SYSTEMBACKDROP_TYPE {
+        _DWMSBT_AUTO,             // [Default] Let DWM automatically decide the system-drawn backdrop for this window.
+        _DWMSBT_NONE,             // [Disable] Do not draw any system backdrop.
+        _DWMSBT_MAINWINDOW,       // [Mica] Draw the backdrop material effect corresponding to a long-lived window.
+        _DWMSBT_TRANSIENTWINDOW,  // [Acrylic] Draw the backdrop material effect corresponding to a transient window.
+        _DWMSBT_TABBEDWINDOW,     // [Mica Alt] Draw the backdrop material effect corresponding to a window with a tabbed title bar.
+    };
+
+    enum WINDOWCOMPOSITIONATTRIB {
+        WCA_UNDEFINED = 0,
+        WCA_NCRENDERING_ENABLED = 1,
+        WCA_NCRENDERING_POLICY = 2,
+        WCA_TRANSITIONS_FORCEDISABLED = 3,
+        WCA_ALLOW_NCPAINT = 4,
+        WCA_CAPTION_BUTTON_BOUNDS = 5,
+        WCA_NONCLIENT_RTL_LAYOUT = 6,
+        WCA_FORCE_ICONIC_REPRESENTATION = 7,
+        WCA_EXTENDED_FRAME_BOUNDS = 8,
+        WCA_HAS_ICONIC_BITMAP = 9,
+        WCA_THEME_ATTRIBUTES = 10,
+        WCA_NCRENDERING_EXILED = 11,
+        WCA_NCADORNMENTINFO = 12,
+        WCA_EXCLUDED_FROM_LIVEPREVIEW = 13,
+        WCA_VIDEO_OVERLAY_ACTIVE = 14,
+        WCA_FORCE_ACTIVEWINDOW_APPEARANCE = 15,
+        WCA_DISALLOW_PEEK = 16,
+        WCA_CLOAK = 17,
+        WCA_CLOAKED = 18,
+        WCA_ACCENT_POLICY = 19,
+        WCA_FREEZE_REPRESENTATION = 20,
+        WCA_EVER_UNCLOAKED = 21,
+        WCA_VISUAL_OWNER = 22,
+        WCA_HOLOGRAPHIC = 23,
+        WCA_EXCLUDED_FROM_DDA = 24,
+        WCA_PASSIVEUPDATEMODE = 25,
+        WCA_USEDARKMODECOLORS = 26,
+        WCA_CORNER_STYLE = 27,
+        WCA_PART_COLOR = 28,
+        WCA_DISABLE_MOVESIZE_FEEDBACK = 29,
+        WCA_LAST = 30
+    };
+
+    enum ACCENT_STATE {
+        ACCENT_DISABLED = 0,
+        ACCENT_ENABLE_GRADIENT = 1,
+        ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
+        ACCENT_ENABLE_BLURBEHIND = 3, // Traditional DWM blur
+        ACCENT_ENABLE_ACRYLICBLURBEHIND = 4, // RS4 1803
+        ACCENT_ENABLE_HOST_BACKDROP = 5, // RS5 1809
+        ACCENT_INVALID_STATE = 6 // Using this value will remove the window background
+    };
+
+    enum ACCENT_FLAG {
+        ACCENT_NONE = 0,
+        ACCENT_ENABLE_ACRYLIC = 1,
+        ACCENT_ENABLE_ACRYLIC_WITH_LUMINOSITY = 482
+    };
+
+    struct ACCENT_POLICY {
+        DWORD dwAccentState;
+        DWORD dwAccentFlags;
+        DWORD dwGradientColor; // #AABBGGRR
+        DWORD dwAnimationId;
+    };
+    using PACCENT_POLICY = ACCENT_POLICY *;
+
+    struct WINDOWCOMPOSITIONATTRIBDATA {
+        WINDOWCOMPOSITIONATTRIB Attrib;
+        PVOID pvData;
+        SIZE_T cbData;
+    };
+    using PWINDOWCOMPOSITIONATTRIBDATA = WINDOWCOMPOSITIONATTRIBDATA *;
+
+    using SetWindowCompositionAttributePtr = BOOL(WINAPI *)(HWND, PWINDOWCOMPOSITIONATTRIBDATA);
+
     // The thickness of an auto-hide taskbar in pixels.
     static constexpr const quint8 kAutoHideTaskBarThickness = 2;
 
@@ -105,6 +181,7 @@
         DYNAMIC_API_DECLARE(DwmGetCompositionTimingInfo);
         DYNAMIC_API_DECLARE(DwmGetWindowAttribute);
         DYNAMIC_API_DECLARE(DwmSetWindowAttribute);
+        DYNAMIC_API_DECLARE(DwmExtendFrameIntoClientArea);
         DYNAMIC_API_DECLARE(GetDpiForWindow);
         DYNAMIC_API_DECLARE(GetSystemMetricsForDpi);
         DYNAMIC_API_DECLARE(GetDpiForMonitor);
@@ -114,6 +191,8 @@
 
 #undef DYNAMIC_API_DECLARE
 
+        SetWindowCompositionAttributePtr pSetWindowCompositionAttribute = nullptr;
+
     private:
         DynamicApis() {
 #define DYNAMIC_API_RESOLVE(DLL, NAME)                                                             \
@@ -122,6 +201,7 @@
             QSystemLibrary user32(QStringLiteral("user32"));
             DYNAMIC_API_RESOLVE(user32, GetDpiForWindow);
             DYNAMIC_API_RESOLVE(user32, GetSystemMetricsForDpi);
+            DYNAMIC_API_RESOLVE(user32, SetWindowCompositionAttribute);
 
             QSystemLibrary shcore(QStringLiteral("shcore"));
             DYNAMIC_API_RESOLVE(shcore, GetDpiForMonitor);
@@ -132,6 +212,7 @@
             DYNAMIC_API_RESOLVE(dwmapi, DwmGetCompositionTimingInfo);
             DYNAMIC_API_RESOLVE(dwmapi, DwmGetWindowAttribute);
             DYNAMIC_API_RESOLVE(dwmapi, DwmSetWindowAttribute);
+            DYNAMIC_API_RESOLVE(dwmapi, DwmExtendFrameIntoClientArea);
 
             QSystemLibrary winmm(QStringLiteral("winmm"));
             DYNAMIC_API_RESOLVE(winmm, timeGetDevCaps);
@@ -243,6 +324,11 @@
 
     static inline bool isWin11OrGreater() {
         static const bool result = IsWindows11OrGreater_Real();
+        return result;
+    }
+
+    static inline bool isWin1122H2OrGreater() {
+        static const bool result = IsWindows1122H2OrGreater_Real();
         return result;
     }
 
@@ -913,37 +999,102 @@
                 const auto &newVar = *static_cast<const QVariant *>(args[1]);
                 const auto &oldVar = *static_cast<const QVariant *>(args[2]);
 
-                if (key == QStringLiteral("no-frame-shadow")) {
-                    if (!windowId)
-                        return;
+                if (!windowId)
+                    return;
+                const auto hwnd = reinterpret_cast<HWND>(windowId);
+
+                const DynamicApis &apis = DynamicApis::instance();
+
+                if (key == QStringLiteral("frame-shadow")) {
                     if (newVar.toBool()) {
                         // TODO: set off
                     } else {
                         // TODO: set on
                     }
-                } else if (key == QStringLiteral("mica-material")) {
-                    if (!windowId || !isWin11OrGreater())
+                } else if (key == QStringLiteral("mica")) {
+                    if (!isWin11OrGreater()) {
                         return;
-                    const auto hwnd = reinterpret_cast<HWND>(windowId);
+                    }
                     if (newVar.toBool()) {
-                        /*
-
                         // We need to extend the window frame into the whole client area to be able
                         // to see the blurred window background.
                         static constexpr const MARGINS margins = {-1, -1, -1, -1};
-                        ::DwmExtendFrameIntoClientArea(hwnd, &margins);
-
-                        // Use official DWM API to enable Mica/Mica Alt, available since Windows 11
-                        // (10.0.22000).
-                        const DWM_SYSTEMBACKDROP_TYPE blurType =
-                            DWMSBT_MAINWINDOW; // This one is Mica, if you want to enable Mica Alt,
-                                               // use DWMSBT_TABBEDWINDOW instead.
-                        DynamicApis::instance().pDwmSetWindowAttribute(
-                            hwnd, DWMWA_SYSTEMBACKDROP_TYPE, &blurType, sizeof(blurType));
-
-                        */
+                        apis.pDwmExtendFrameIntoClientArea(hwnd, &margins);
+                        if (isWin1122H2OrGreater()) {
+                            // Use official DWM API to enable Mica, available since Windows 11 22H2 (10.0.22621).
+                            const _DWM_SYSTEMBACKDROP_TYPE backdropType = _DWMSBT_MAINWINDOW;
+                            apis.pDwmSetWindowAttribute(hwnd, _DWMWA_SYSTEMBACKDROP_TYPE, &backdropType, sizeof(backdropType));
+                        } else {
+                            // Use undocumented DWM API to enable Mica, available since Windows 11 (10.0.22000).
+                            const BOOL enable = TRUE;
+                            apis.pDwmSetWindowAttribute(hwnd, _DWMWA_MICA_EFFECT, &enable, sizeof(enable));
+                        }
                     } else {
-                        // TODO: set off
+                        if (isWin1122H2OrGreater()) {
+                            const _DWM_SYSTEMBACKDROP_TYPE backdropType = _DWMSBT_AUTO;
+                            apis.pDwmSetWindowAttribute(hwnd, _DWMWA_SYSTEMBACKDROP_TYPE, &backdropType, sizeof(backdropType));
+                        } else {
+                            const BOOL enable = FALSE;
+                            apis.pDwmSetWindowAttribute(hwnd, _DWMWA_MICA_EFFECT, &enable, sizeof(enable));
+                        }
+                        static constexpr const MARGINS margins = {0, 0, 0, 0};
+                        apis.pDwmExtendFrameIntoClientArea(hwnd, &margins);
+                    }
+                } else if (key == QStringLiteral("mica-alt")) {
+                    if (!isWin1122H2OrGreater()) {
+                        return;
+                    }
+                    if (newVar.toBool()) {
+                        // We need to extend the window frame into the whole client area to be able
+                        // to see the blurred window background.
+                        static constexpr const MARGINS margins = {-1, -1, -1, -1};
+                        apis.pDwmExtendFrameIntoClientArea(hwnd, &margins);
+                        // Use official DWM API to enable Mica Alt, available since Windows 11 22H2 (10.0.22621).
+                        const _DWM_SYSTEMBACKDROP_TYPE backdropType = _DWMSBT_TABBEDWINDOW;
+                        apis.pDwmSetWindowAttribute(hwnd, _DWMWA_SYSTEMBACKDROP_TYPE, &backdropType, sizeof(backdropType));
+                    } else {
+                        const _DWM_SYSTEMBACKDROP_TYPE backdropType = _DWMSBT_AUTO;
+                        apis.pDwmSetWindowAttribute(hwnd, _DWMWA_SYSTEMBACKDROP_TYPE, &backdropType, sizeof(backdropType));
+                        static constexpr const MARGINS margins = {0, 0, 0, 0};
+                        apis.pDwmExtendFrameIntoClientArea(hwnd, &margins);
+                    }
+                } else if (key == QStringLiteral("acrylic-material")) {
+                    if (newVar.toBool()) {
+                        // We need to extend the window frame into the whole client area to be able
+                        // to see the blurred window background.
+                        static constexpr const MARGINS margins = {-1, -1, -1, -1};
+                        apis.pDwmExtendFrameIntoClientArea(hwnd, &margins);
+                        if (isWin11OrGreater()) {
+                            const _DWM_SYSTEMBACKDROP_TYPE backdropType = _DWMSBT_TRANSIENTWINDOW;
+                            apis.pDwmSetWindowAttribute(hwnd, _DWMWA_SYSTEMBACKDROP_TYPE, &backdropType, sizeof(backdropType));
+                        } else {
+                            ACCENT_POLICY policy{};
+                            policy.dwAccentState = ACCENT_ENABLE_ACRYLICBLURBEHIND;
+                            policy.dwAccentFlags = ACCENT_ENABLE_ACRYLIC_WITH_LUMINOSITY;
+                            // This API expects the #AABBGGRR format.
+                            //policy.dwGradientColor = DWORD(qRgba(gradientColor.blue(), gradientColor.green(), gradientColor.red(), gradientColor.alpha()));
+                            WINDOWCOMPOSITIONATTRIBDATA wcad{};
+                            wcad.Attrib = WCA_ACCENT_POLICY;
+                            wcad.pvData = &policy;
+                            wcad.cbData = sizeof(policy);
+                            apis.pSetWindowCompositionAttribute(hwnd, &wcad);
+                        }
+                    } else {
+                        if (isWin11OrGreater()) {
+                            const _DWM_SYSTEMBACKDROP_TYPE backdropType = _DWMSBT_AUTO;
+                            apis.pDwmSetWindowAttribute(hwnd, _DWMWA_SYSTEMBACKDROP_TYPE, &backdropType, sizeof(backdropType));
+                        } else {
+                            ACCENT_POLICY policy{};
+                            policy.dwAccentState = ACCENT_DISABLED;
+                            policy.dwAccentFlags = ACCENT_NONE;
+                            WINDOWCOMPOSITIONATTRIBDATA wcad{};
+                            wcad.Attrib = WCA_ACCENT_POLICY;
+                            wcad.pvData = &policy;
+                            wcad.cbData = sizeof(policy);
+                            apis.pSetWindowCompositionAttribute(hwnd, &wcad);
+                        }
+                        static constexpr const MARGINS margins = {0, 0, 0, 0};
+                        apis.pDwmExtendFrameIntoClientArea(hwnd, &margins);
                     }
                 }
                 return;

--
Gitblit v1.9.1