| | |
| | | // version without notice, or may even be removed. |
| | | // |
| | | |
| | | #include <shellscalingapi.h> |
| | | #include <dwmapi.h> |
| | | #include <timeapi.h> |
| | | |
| | | #include <QWKCore/qwindowkit_windows.h> |
| | | #include <QtCore/private/qsystemlibrary_p.h> |
| | | |
| | | #include <QtCore/QtMath> |
| | | #include <QtGui/QGuiApplication> |
| | | #include <QtGui/QStyleHints> |
| | | #include <QtGui/QPalette> |
| | | |
| | | #include <QtCore/private/qsystemlibrary_p.h> |
| | | |
| | | // Don't include this header in any header files. |
| | | |
| | | typedef struct _MARGINS |
| | | { |
| | | int cxLeftWidth; |
| | | int cxRightWidth; |
| | | int cyTopHeight; |
| | | int cyBottomHeight; |
| | | } MARGINS, *PMARGINS; |
| | | |
| | | typedef enum MONITOR_DPI_TYPE { |
| | | MDT_EFFECTIVE_DPI = 0, |
| | | MDT_ANGULAR_DPI = 1, |
| | | MDT_RAW_DPI = 2, |
| | | MDT_DEFAULT = MDT_EFFECTIVE_DPI |
| | | } MONITOR_DPI_TYPE; |
| | | |
| | | typedef struct _DWM_BLURBEHIND |
| | | { |
| | | DWORD dwFlags; |
| | | BOOL fEnable; |
| | | HRGN hRgnBlur; |
| | | BOOL fTransitionOnMaximized; |
| | | } DWM_BLURBEHIND, *PDWM_BLURBEHIND; |
| | | |
| | | extern "C" { |
| | | UINT WINAPI GetDpiForWindow(HWND); |
| | | int WINAPI GetSystemMetricsForDpi(int, UINT); |
| | | HRESULT WINAPI GetDpiForMonitor(HMONITOR, MONITOR_DPI_TYPE, UINT *, UINT *); |
| | | HRESULT WINAPI DwmFlush(); |
| | | HRESULT WINAPI DwmIsCompositionEnabled(BOOL*); |
| | | HRESULT WINAPI DwmGetWindowAttribute(HWND, DWORD, PVOID, DWORD); |
| | | HRESULT WINAPI DwmSetWindowAttribute(HWND, DWORD, LPCVOID, DWORD); |
| | | HRESULT WINAPI DwmExtendFrameIntoClientArea(HWND, const MARGINS*); |
| | | HRESULT WINAPI DwmEnableBlurBehindWindow(HWND, const DWM_BLURBEHIND*); |
| | | } // extern "C" |
| | | |
| | | namespace QWK { |
| | | |
| | |
| | | namespace { |
| | | |
| | | struct DynamicApis { |
| | | static const DynamicApis &instance() { |
| | | static inline const DynamicApis &instance() { |
| | | static const DynamicApis inst; |
| | | return inst; |
| | | } |
| | |
| | | |
| | | DYNAMIC_API_DECLARE(DwmFlush); |
| | | DYNAMIC_API_DECLARE(DwmIsCompositionEnabled); |
| | | DYNAMIC_API_DECLARE(DwmGetCompositionTimingInfo); |
| | | DYNAMIC_API_DECLARE(DwmGetWindowAttribute); |
| | | DYNAMIC_API_DECLARE(DwmSetWindowAttribute); |
| | | DYNAMIC_API_DECLARE(DwmExtendFrameIntoClientArea); |
| | |
| | | DYNAMIC_API_DECLARE(GetSystemMetricsForDpi); |
| | | DYNAMIC_API_DECLARE(AdjustWindowRectExForDpi); |
| | | DYNAMIC_API_DECLARE(GetDpiForMonitor); |
| | | DYNAMIC_API_DECLARE(timeGetDevCaps); |
| | | DYNAMIC_API_DECLARE(timeBeginPeriod); |
| | | DYNAMIC_API_DECLARE(timeEndPeriod); |
| | | |
| | | #undef DYNAMIC_API_DECLARE |
| | | |
| | |
| | | SetPreferredAppModePtr pSetPreferredAppMode = nullptr; |
| | | |
| | | private: |
| | | DynamicApis() { |
| | | inline DynamicApis() { |
| | | #define DYNAMIC_API_RESOLVE(DLL, NAME) \ |
| | | p##NAME = reinterpret_cast<decltype(p##NAME)>(DLL.resolve(#NAME)) |
| | | |
| | |
| | | QSystemLibrary dwmapi(QStringLiteral("dwmapi")); |
| | | DYNAMIC_API_RESOLVE(dwmapi, DwmFlush); |
| | | DYNAMIC_API_RESOLVE(dwmapi, DwmIsCompositionEnabled); |
| | | DYNAMIC_API_RESOLVE(dwmapi, DwmGetCompositionTimingInfo); |
| | | DYNAMIC_API_RESOLVE(dwmapi, DwmGetWindowAttribute); |
| | | DYNAMIC_API_RESOLVE(dwmapi, DwmSetWindowAttribute); |
| | | DYNAMIC_API_RESOLVE(dwmapi, DwmExtendFrameIntoClientArea); |
| | | DYNAMIC_API_RESOLVE(dwmapi, DwmEnableBlurBehindWindow); |
| | | |
| | | QSystemLibrary winmm(QStringLiteral("winmm")); |
| | | DYNAMIC_API_RESOLVE(winmm, timeGetDevCaps); |
| | | DYNAMIC_API_RESOLVE(winmm, timeBeginPeriod); |
| | | DYNAMIC_API_RESOLVE(winmm, timeEndPeriod); |
| | | |
| | | #undef DYNAMIC_API_RESOLVE |
| | | |
| | |
| | | #undef UNDOC_API_RESOLVE |
| | | } |
| | | |
| | | ~DynamicApis() = default; |
| | | inline ~DynamicApis() = default; |
| | | |
| | | Q_DISABLE_COPY(DynamicApis) |
| | | }; |
| | |
| | | if (!registry.isValid()) { |
| | | return false; |
| | | } |
| | | auto value = registry.value<DWORD>(L"ColorPrevalence"); |
| | | return value.value_or(false); |
| | | auto value = registry.dwordValue(L"ColorPrevalence"); |
| | | if (!value.second) { |
| | | return false; |
| | | } |
| | | return value.first; |
| | | } |
| | | |
| | | inline bool isHighContrastModeEnabled() { |
| | |
| | | if (!registry.isValid()) { |
| | | return false; |
| | | } |
| | | auto value = registry.value<DWORD>(L"AppsUseLightTheme"); |
| | | return value.value_or(false); |
| | | auto value = registry.dwordValue(L"AppsUseLightTheme"); |
| | | if (!value.second) { |
| | | return false; |
| | | } |
| | | return !value.first; |
| | | #endif |
| | | } |
| | | |
| | |
| | | } |
| | | BOOL enabled = FALSE; |
| | | const DynamicApis &apis = DynamicApis::instance(); |
| | | const auto attr = isWin1020H1OrGreater() ? _DWMWA_USE_IMMERSIVE_DARK_MODE : _DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1; |
| | | return SUCCEEDED(apis.pDwmGetWindowAttribute(hwnd, attr, &enabled, sizeof(enabled))) && enabled; |
| | | const auto attr = isWin1020H1OrGreater() ? _DWMWA_USE_IMMERSIVE_DARK_MODE |
| | | : _DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1; |
| | | return SUCCEEDED(apis.pDwmGetWindowAttribute(hwnd, attr, &enabled, sizeof(enabled))) && |
| | | enabled; |
| | | } |
| | | |
| | | inline QColor getAccentColor() { |
| | |
| | | if (!registry.isValid()) { |
| | | return {}; |
| | | } |
| | | auto value = registry.value<DWORD>(L"AccentColor"); |
| | | if (!value) { |
| | | auto value = registry.dwordValue(L"AccentColor"); |
| | | if (!value.second) { |
| | | return {}; |
| | | } |
| | | // The retrieved value is in the #AABBGGRR format, we need to |
| | | // convert it to the #AARRGGBB format which Qt expects. |
| | | QColor color = QColor::fromRgba(*value); |
| | | QColor color = QColor::fromRgba(value.first); |
| | | if (!color.isValid()) { |
| | | return {}; |
| | | } |
| | |
| | | |
| | | inline quint32 getDpiForWindow(HWND hwnd) { |
| | | const DynamicApis &apis = DynamicApis::instance(); |
| | | if (apis.pGetDpiForWindow) { // Win10 |
| | | if (apis.pGetDpiForWindow) { // Win10 |
| | | return apis.pGetDpiForWindow(hwnd); |
| | | } else if (apis.pGetDpiForMonitor) { // Win8.1 |
| | | HMONITOR monitor = ::MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); |