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 | 70 ++++++++++++++++++++++++++++++++-- 1 files changed, 65 insertions(+), 5 deletions(-) diff --git a/src/core/shared/qwkwindowsextra_p.h b/src/core/shared/qwkwindowsextra_p.h index 850f0a2..15fe4e7 100644 --- a/src/core/shared/qwkwindowsextra_p.h +++ b/src/core/shared/qwkwindowsextra_p.h @@ -16,11 +16,12 @@ #include <QWKCore/qwindowkit_windows.h> -#include <QtGui/QStyleHints> -#include <QtGui/QPalette> - #include <QtCore/private/qsystemlibrary_p.h> #include <QtCore/private/qwinregistry_p.h> + +#include <QtGui/QGuiApplication> +#include <QtGui/QStyleHints> +#include <QtGui/QPalette> // Don't include this header in any header files. @@ -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