From 29901fc2a97eedd3c914f807d1819c9ea7e69973 Mon Sep 17 00:00:00 2001
From: Sine Striker <trueful@163.com>
Date: 周一, 25 12月 2023 17:53:34 +0800
Subject: [PATCH] Optimize Windows 10 border handling

---
 src/core/shared/qwkwindowsextra_p.h |   64 +++++++++++++++++++++++++++++++-
 1 files changed, 62 insertions(+), 2 deletions(-)

diff --git a/src/core/shared/qwkwindowsextra_p.h b/src/core/shared/qwkwindowsextra_p.h
index 03adf7e..15fe4e7 100644
--- a/src/core/shared/qwkwindowsextra_p.h
+++ b/src/core/shared/qwkwindowsextra_p.h
@@ -19,6 +19,7 @@
 #include <QtCore/private/qsystemlibrary_p.h>
 #include <QtCore/private/qwinregistry_p.h>
 
+#include <QtGui/QGuiApplication>
 #include <QtGui/QStyleHints>
 #include <QtGui/QPalette>
 
@@ -131,7 +132,24 @@
     };
     using PWINDOWCOMPOSITIONATTRIBDATA = WINDOWCOMPOSITIONATTRIBDATA *;
 
+    enum PREFERRED_APP_MODE
+    {
+        PAM_DEFAULT = 0, // Default behavior on systems before Win10 1809. It indicates the application doesn't support dark mode at all.
+        PAM_AUTO = 1, // Available since Win10 1809, let system decide whether to enable dark mode or not.
+        PAM_DARK = 2, // Available since Win10 1903, force dark mode regardless of the system theme.
+        PAM_LIGHT = 3, // Available since Win10 1903, force light mode regardless of the system theme.
+        PAM_MAX = 4
+    };
+
     using SetWindowCompositionAttributePtr = BOOL(WINAPI *)(HWND, PWINDOWCOMPOSITIONATTRIBDATA);
+
+    // Win10 1809 (10.0.17763)
+    using RefreshImmersiveColorPolicyStatePtr = VOID(WINAPI *)(VOID); // Ordinal 104
+    using AllowDarkModeForWindowPtr = BOOL(WINAPI *)(HWND, BOOL);     // Ordinal 133
+    using AllowDarkModeForAppPtr = BOOL(WINAPI *)(BOOL);              // Ordinal 135
+    using FlushMenuThemesPtr = VOID(WINAPI *)(VOID);                  // Ordinal 136
+    // Win10 1903 (10.0.18362)
+    using SetPreferredAppModePtr = PREFERRED_APP_MODE(WINAPI *)(PREFERRED_APP_MODE); // Ordinal 135
 
     namespace {
 
@@ -160,6 +178,11 @@
 #undef DYNAMIC_API_DECLARE
 
             SetWindowCompositionAttributePtr pSetWindowCompositionAttribute = nullptr;
+            RefreshImmersiveColorPolicyStatePtr pRefreshImmersiveColorPolicyState = nullptr;
+            AllowDarkModeForWindowPtr pAllowDarkModeForWindow = nullptr;
+            AllowDarkModeForAppPtr pAllowDarkModeForApp = nullptr;
+            FlushMenuThemesPtr pFlushMenuThemes = nullptr;
+            SetPreferredAppModePtr pSetPreferredAppMode = nullptr;
 
         private:
             DynamicApis() {
@@ -189,6 +212,18 @@
                 DYNAMIC_API_RESOLVE(winmm, timeEndPeriod);
 
 #undef DYNAMIC_API_RESOLVE
+
+#define UNDOC_API_RESOLVE(DLL, NAME, ORDINAL)                                                      \
+    p##NAME = reinterpret_cast<decltype(p##NAME)>(DLL.resolve(MAKEINTRESOURCEA(ORDINAL)))
+
+                QSystemLibrary uxtheme(QStringLiteral("uxtheme"));
+                UNDOC_API_RESOLVE(uxtheme, RefreshImmersiveColorPolicyState, 104);
+                UNDOC_API_RESOLVE(uxtheme, AllowDarkModeForWindow, 133);
+                UNDOC_API_RESOLVE(uxtheme, AllowDarkModeForApp, 135);
+                UNDOC_API_RESOLVE(uxtheme, FlushMenuThemes, 136);
+                UNDOC_API_RESOLVE(uxtheme, SetPreferredAppMode, 135);
+
+#undef UNDOC_API_RESOLVE
             }
 
             ~DynamicApis() = default;
@@ -267,6 +302,15 @@
                     LONG(qrect.bottom())};
     }
 
+    static inline constexpr QMargins margins2qmargins(const MARGINS &margins) {
+        return {margins.cxLeftWidth, margins.cyTopHeight, margins.cxRightWidth,
+                margins.cyBottomHeight};
+    }
+
+    static inline constexpr MARGINS qmargins2margins(const QMargins &qmargins) {
+        return MARGINS{qmargins.left(), qmargins.right(), qmargins.top(), qmargins.bottom()};
+    }
+
     static inline /*constexpr*/ QString hwnd2str(const WId windowId) {
         // NULL handle is allowed here.
         return QLatin1String("0x") +
@@ -290,6 +334,16 @@
 
     static inline bool isWin10OrGreater() {
         static const bool result = IsWindows10OrGreater_Real();
+        return result;
+    }
+
+    static inline bool isWin101809OrGreater() {
+        static const bool result = IsWindows101809OrGreater_Real();
+        return result;
+    }
+
+    static inline bool isWin101903OrGreater() {
+        static const bool result = IsWindows101903OrGreater_Real();
         return result;
     }
 
@@ -327,6 +381,13 @@
         return value.first;
     }
 
+    static inline bool isHighContrastModeEnabled() {
+        HIGHCONTRASTW hc{};
+        hc.cbSize = sizeof(hc);
+        ::SystemParametersInfoW(SPI_GETHIGHCONTRAST, sizeof(hc), &hc, FALSE);
+        return (hc.dwFlags & HCF_HIGHCONTRASTON);
+    }
+
     static inline bool isDarkThemeActive() {
 #if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
         return QGuiApplication::styleHints()->colorScheme() == Qt::ColorScheme::Dark;
@@ -354,9 +415,8 @@
                                                          _DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1,
                                                          &enabled, sizeof(enabled)))) {
             return enabled;
-        } else {
-            return false;
         }
+        return false;
     }
 
     static inline QColor getAccentColor() {

--
Gitblit v1.9.1