diff --git a/include/FramelessHelper/Core/utils.h b/include/FramelessHelper/Core/utils.h index a569d6b..97421ab 100644 --- a/include/FramelessHelper/Core/utils.h +++ b/include/FramelessHelper/Core/utils.h @@ -52,7 +52,6 @@ FRAMELESSHELPER_CORE_API void startSystemResize(QWindow *window, const Qt::Edges [[nodiscard]] FRAMELESSHELPER_CORE_API QWindow *findWindow(const WId windowId); FRAMELESSHELPER_CORE_API void moveWindowToDesktopCenter( const SystemParameters *params, const bool considerTaskBar); -[[nodiscard]] FRAMELESSHELPER_CORE_API Global::SystemTheme getSystemTheme(); [[nodiscard]] FRAMELESSHELPER_CORE_API Qt::WindowState windowStatesToWindowState( const Qt::WindowStates states); [[nodiscard]] FRAMELESSHELPER_CORE_API bool isThemeChangeEvent(const QEvent * const event); @@ -84,6 +83,10 @@ FRAMELESSHELPER_CORE_API void registerThemeChangeNotification(); [[nodiscard]] FRAMELESSHELPER_CORE_API qreal getRelativeScaleFactor(const quint32 oldDpi, const quint32 newDpi); [[nodiscard]] FRAMELESSHELPER_CORE_API QSize rescaleSize(const QSize &oldSize, const quint32 oldDpi, const quint32 newDpi); [[nodiscard]] FRAMELESSHELPER_CORE_API bool isValidGeometry(const QRect &rect); +[[nodiscard]] FRAMELESSHELPER_CORE_API QColor getAccentColor(); +[[nodiscard]] FRAMELESSHELPER_CORE_API quint32 defaultScreenDpi(); +[[nodiscard]] FRAMELESSHELPER_CORE_API qreal getRealDevicePixelRatio(const QWindow *window); +[[nodiscard]] FRAMELESSHELPER_CORE_API qreal getQtDevicePixelRatio(const QWindow *window); #ifdef Q_OS_WINDOWS [[nodiscard]] FRAMELESSHELPER_CORE_API bool isWindowsVersionOrGreater(const Global::WindowsVersion version); @@ -125,8 +128,8 @@ FRAMELESSHELPER_CORE_API void setAeroSnappingEnabled(const WId windowId, const b FRAMELESSHELPER_CORE_API void tryToEnableHighestDpiAwarenessLevel(); FRAMELESSHELPER_CORE_API void updateGlobalWin32ControlsTheme(const WId windowId, const bool dark); [[nodiscard]] FRAMELESSHELPER_CORE_API bool shouldAppsUseDarkMode_windows(); +[[nodiscard]] FRAMELESSHELPER_CORE_API QColor getAccentColor_windows(); FRAMELESSHELPER_CORE_API void setCornerStyleForWindow(const WId windowId, const Global::WindowCornerStyle style); -[[nodiscard]] FRAMELESSHELPER_CORE_API QColor getDwmAccentColor(); FRAMELESSHELPER_CORE_API void hideOriginalTitleBarElements (const WId windowId, const bool disable = true); FRAMELESSHELPER_CORE_API void setQtDarkModeAwareEnabled(const bool enable); @@ -168,7 +171,7 @@ FRAMELESSHELPER_CORE_API void clearWindowProperty(const WId windowId, const xcb_ [[nodiscard]] FRAMELESSHELPER_CORE_API bool tryHideSystemTitleBar(const WId windowId, const bool hide = true); FRAMELESSHELPER_CORE_API void openSystemMenu(const WId windowId, const QPoint &globalPos); [[nodiscard]] FRAMELESSHELPER_CORE_API bool shouldAppsUseDarkMode_linux(); -[[nodiscard]] FRAMELESSHELPER_CORE_API QColor getWmThemeColor(); +[[nodiscard]] FRAMELESSHELPER_CORE_API QColor getAccentColor_linux(); FRAMELESSHELPER_CORE_API void sendMoveResizeMessage (const WId windowId, const uint32_t action, const QPoint &globalPos, const Qt::MouseButton button = Qt::LeftButton); [[nodiscard]] FRAMELESSHELPER_CORE_API bool isCustomDecorationSupported(); @@ -178,8 +181,8 @@ FRAMELESSHELPER_CORE_API void sendMoveResizeMessage #ifdef Q_OS_MACOS [[nodiscard]] FRAMELESSHELPER_CORE_API bool shouldAppsUseDarkMode_macos(); +[[nodiscard]] FRAMELESSHELPER_CORE_API QColor getAccentColor_macos(); FRAMELESSHELPER_CORE_API void setSystemTitleBarVisible(const WId windowId, const bool visible); -[[nodiscard]] FRAMELESSHELPER_CORE_API QColor getControlsAccentColor(); FRAMELESSHELPER_CORE_API void removeWindowProxy(const WId windowId); #endif // Q_OS_MACOS } // namespace Utils diff --git a/src/core/chromepalette.cpp b/src/core/chromepalette.cpp index ef66180..20ee2cb 100644 --- a/src/core/chromepalette.cpp +++ b/src/core/chromepalette.cpp @@ -84,15 +84,7 @@ void ChromePalettePrivate::refresh() const bool dark = (FramelessManager::instance()->systemTheme() == SystemTheme::Dark); titleBarActiveBackgroundColor_sys = [colorized, dark]() -> QColor { if (colorized) { -#ifdef Q_OS_WINDOWS - return Utils::getDwmAccentColor(); -#elif defined(Q_OS_LINUX) - return Utils::getWmThemeColor(); -#elif defined(Q_OS_MACOS) - return Utils::getControlsAccentColor(); -#else - return {}; -#endif + return Utils::getAccentColor(); } else { return (dark ? kDefaultBlackColor : kDefaultWhiteColor); } diff --git a/src/core/framelesshelpercore_global.cpp b/src/core/framelesshelpercore_global.cpp index 9bbeff6..1f09a70 100644 --- a/src/core/framelesshelpercore_global.cpp +++ b/src/core/framelesshelpercore_global.cpp @@ -86,12 +86,7 @@ QDebug operator<<(QDebug d, const FRAMELESSHELPER_PREPEND_NAMESPACE(Global)::Ver QDebug operator<<(QDebug d, const FRAMELESSHELPER_PREPEND_NAMESPACE(Global)::Dpi &dpi) { const QDebugStateSaver saver(d); -#ifdef Q_OS_MACOS - static constexpr const auto defaultDpi = quint32(72); -#else // !Q_OS_MACOS - static constexpr const auto defaultDpi = quint32(96); -#endif // Q_OS_MACOS - const qreal scaleFactor = (qreal(dpi.x) / qreal(defaultDpi)); + const qreal scaleFactor = (qreal(dpi.x) / qreal(FRAMELESSHELPER_PREPEND_NAMESPACE(Utils)::defaultScreenDpi())); d.nospace().noquote() << "Dpi(" << "x: " << dpi.x << ", " << "y: " << dpi.y << ", " diff --git a/src/core/framelessmanager.cpp b/src/core/framelessmanager.cpp index a1cdbfe..c409bf9 100644 --- a/src/core/framelessmanager.cpp +++ b/src/core/framelessmanager.cpp @@ -238,16 +238,10 @@ void FramelessManagerPrivate::removeWindow(const WId windowId) void FramelessManagerPrivate::notifySystemThemeHasChangedOrNot() { - const SystemTheme currentSystemTheme = Utils::getSystemTheme(); + const SystemTheme currentSystemTheme = (Utils::shouldAppsUseDarkMode() ? SystemTheme::Dark : SystemTheme::Light); + const QColor currentAccentColor = Utils::getAccentColor(); #ifdef Q_OS_WINDOWS const DwmColorizationArea currentColorizationArea = Utils::getDwmColorizationArea(); - const QColor currentAccentColor = Utils::getDwmAccentColor(); -#endif -#ifdef Q_OS_LINUX - const QColor currentAccentColor = Utils::getWmThemeColor(); -#endif -#ifdef Q_OS_MACOS - const QColor currentAccentColor = Utils::getControlsAccentColor(); #endif bool notify = false; if (m_systemTheme != currentSystemTheme) { @@ -332,16 +326,10 @@ bool FramelessManagerPrivate::isThemeOverrided() const void FramelessManagerPrivate::initialize() { - m_systemTheme = Utils::getSystemTheme(); + m_systemTheme = (Utils::shouldAppsUseDarkMode() ? SystemTheme::Dark : SystemTheme::Light); + m_accentColor = Utils::getAccentColor(); #ifdef Q_OS_WINDOWS m_colorizationArea = Utils::getDwmColorizationArea(); - m_accentColor = Utils::getDwmAccentColor(); -#endif -#ifdef Q_OS_LINUX - m_accentColor = Utils::getWmThemeColor(); -#endif -#ifdef Q_OS_MACOS - m_accentColor = Utils::getControlsAccentColor(); #endif m_wallpaper = Utils::getWallpaperFilePath(); m_wallpaperAspectStyle = Utils::getWallpaperAspectStyle(); diff --git a/src/core/utils.cpp b/src/core/utils.cpp index 20a04d5..d6231bf 100644 --- a/src/core/utils.cpp +++ b/src/core/utils.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #ifndef FRAMELESSHELPER_CORE_NO_PRIVATE # include #endif // FRAMELESSHELPER_CORE_NO_PRIVATE @@ -276,15 +277,7 @@ QColor Utils::calculateSystemButtonBackgroundColor(const SystemButtonType button return kDefaultSystemCloseButtonBackgroundColor; } if (isTitleColor) { -#ifdef Q_OS_WINDOWS - return getDwmAccentColor(); -#endif -#ifdef Q_OS_LINUX - return getWmThemeColor(); -#endif -#ifdef Q_OS_MACOS - return getControlsAccentColor(); -#endif + return getAccentColor(); } return kDefaultSystemButtonBackgroundColor; }(); @@ -527,11 +520,7 @@ qreal Utils::getRelativeScaleFactor(const quint32 oldDpi, const quint32 newDpi) if (newDpi == oldDpi) { return qreal(1); } -#ifdef Q_OS_MACOS - static constexpr const auto defaultDpi = quint32(72); -#else // !Q_OS_MACOS - static constexpr const auto defaultDpi = quint32(96); -#endif // Q_OS_MACOS + static const quint32 defaultDpi = defaultScreenDpi(); if ((oldDpi < defaultDpi) || (newDpi < defaultDpi)) { return qreal(1); } @@ -566,4 +555,50 @@ bool Utils::isValidGeometry(const QRect &rect) return ((rect.right() > rect.left()) && (rect.bottom() > rect.top())); } +quint32 Utils::defaultScreenDpi() +{ +#ifdef Q_OS_MACOS + return 72; +#else // !Q_OS_MACOS + return 96; +#endif // Q_OS_MACOS +} + +qreal Utils::getRealDevicePixelRatio(const QWindow *window) +{ + Q_ASSERT(window); + if (!window) { + return qreal(1); + } + // Qt doesn't support device pixel ratio smaller than 1. + return std::max(qreal(getDpiForWindow(window)) / qreal(defaultScreenDpi()), qreal(1)); +} + +qreal Utils::getQtDevicePixelRatio(const QWindow *window) +{ + Q_ASSERT(window); + if (!window) { + return qreal(1); + } + // Apply the rounding policy from Qt, most probably set by the user. + return roundScaleFactor(getRealDevicePixelRatio(window)); +} + +QColor Utils::getAccentColor() +{ +#if (QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)) + return QGuiApplication::palette().color(QPalette::AccentColor); +#else // (QT_VERSION < QT_VERSION_CHECK(6, 6, 0)) +# ifdef Q_OS_WINDOWS + return getAccentColor_windows(); +# elif defined(Q_OS_LINUX) + return getAccentColor_linux(); +# elif defined(Q_OS_MACOS) + return getAccentColor_macos(); +# else + return QGuiApplication::palette().color(QPalette::Highlight); +# endif +#endif // (QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)) +} + FRAMELESSHELPER_END_NAMESPACE diff --git a/src/core/utils_linux.cpp b/src/core/utils_linux.cpp index a049445..0be7415 100644 --- a/src/core/utils_linux.cpp +++ b/src/core/utils_linux.cpp @@ -344,12 +344,6 @@ xcb_connection_t *Utils::x11_connection() #endif // FRAMELESSHELPER_HAS_X11EXTRAS } -SystemTheme Utils::getSystemTheme() -{ - // ### TODO: how to detect high contrast mode on Linux? - return (shouldAppsUseDarkMode() ? SystemTheme::Dark : SystemTheme::Light); -} - void Utils::startSystemMove(QWindow *window, const QPoint &globalPos) { Q_ASSERT(window); @@ -390,7 +384,7 @@ bool Utils::isTitleBarColorized() return false; } -QColor Utils::getWmThemeColor() +QColor Utils::getAccentColor_linux() { // ### TODO return QGuiApplication::palette().color(QPalette::Highlight); @@ -577,7 +571,7 @@ void Utils::registerThemeChangeNotification() QColor Utils::getFrameBorderColor(const bool active) { - return (active ? getWmThemeColor() : kDefaultDarkGrayColor); + return (active ? getAccentColor() : kDefaultDarkGrayColor); } xcb_atom_t Utils::internAtom(const char *name) diff --git a/src/core/utils_mac.mm b/src/core/utils_mac.mm index b717643..5908d89 100644 --- a/src/core/utils_mac.mm +++ b/src/core/utils_mac.mm @@ -615,12 +615,6 @@ static inline void cleanupProxy() return g_macUtilsData()->hash.value(windowId); } -SystemTheme Utils::getSystemTheme() -{ - // ### TODO: how to detect high contrast mode on macOS? - return (shouldAppsUseDarkMode() ? SystemTheme::Dark : SystemTheme::Light); -} - void Utils::setSystemTitleBarVisible(const WId windowId, const bool visible) { Q_ASSERT(windowId); @@ -678,7 +672,7 @@ void Utils::startSystemResize(QWindow *window, const Qt::Edges edges, const QPoi #endif } -QColor Utils::getControlsAccentColor() +QColor Utils::getAccentColor_macos() { return qt_mac_toQColor([NSColor controlAccentColor]); } @@ -793,7 +787,7 @@ void Utils::removeWindowProxy(const WId windowId) QColor Utils::getFrameBorderColor(const bool active) { - return (active ? getControlsAccentColor() : kDefaultDarkGrayColor); + return (active ? getAccentColor() : kDefaultDarkGrayColor); } FRAMELESSHELPER_END_NAMESPACE diff --git a/src/core/utils_win.cpp b/src/core/utils_win.cpp index 4583ea8..c2607e9 100644 --- a/src/core/utils_win.cpp +++ b/src/core/utils_win.cpp @@ -1262,10 +1262,10 @@ QColor Utils::getFrameBorderColor(const bool active) if (!WindowsVersionHelper::isWin10OrGreater()) { return (active ? kDefaultBlackColor : kDefaultDarkGrayColor); } - const bool dark = shouldAppsUseDarkMode(); + const bool dark = (FramelessManager::instance()->systemTheme() == SystemTheme::Dark); if (active) { if (isFrameBorderColorized()) { - return getDwmAccentColor(); + return getAccentColor(); } return (dark ? kDefaultFrameBorderActiveColor : kDefaultTransparentColor); } else { @@ -1601,17 +1601,6 @@ void Utils::tryToEnableHighestDpiAwarenessLevel() } } -SystemTheme Utils::getSystemTheme() -{ - if (isHighContrastModeEnabled()) { - return SystemTheme::HighContrast; - } - if (WindowsVersionHelper::isWin10RS1OrGreater() && shouldAppsUseDarkMode()) { - return SystemTheme::Dark; - } - return SystemTheme::Light; -} - void Utils::updateGlobalWin32ControlsTheme(const WId windowId, const bool dark) { Q_ASSERT(windowId); @@ -1636,7 +1625,7 @@ void Utils::updateGlobalWin32ControlsTheme(const WId windowId, const bool dark) bool Utils::shouldAppsUseDarkMode_windows() { // The global dark mode was first introduced in Windows 10 1607. - if (!WindowsVersionHelper::isWin10RS1OrGreater()) { + if (!WindowsVersionHelper::isWin10RS1OrGreater() || isHighContrastModeEnabled()) { return false; } #ifndef FRAMELESSHELPER_CORE_NO_PRIVATE @@ -1856,7 +1845,7 @@ bool Utils::setBlurBehindWindowEnabled(const WId windowId, const BlurMode mode, if (color.isValid()) { return color; } - QColor clr = (shouldAppsUseDarkMode() ? kDefaultSystemDarkColor : kDefaultSystemLightColor); + QColor clr = ((FramelessManager::instance()->systemTheme() == SystemTheme::Dark) ? kDefaultSystemDarkColor : kDefaultSystemLightColor); clr.setAlphaF(0.9f); return clr; }(); @@ -1917,9 +1906,9 @@ bool Utils::setBlurBehindWindowEnabled(const WId windowId, const BlurMode mode, return false; } -QColor Utils::getDwmAccentColor() +QColor Utils::getAccentColor_windows() { - // According to my test, this AccentColor will be exactly the same with + // According to my experiments, this AccentColor will be exactly the same with // ColorizationColor, what's the meaning of it? But Microsoft products // usually read this setting instead of using DwmGetColorizationColor(), // so we'd better also do the same thing. @@ -1935,7 +1924,7 @@ QColor Utils::getDwmAccentColor() return alternative; } // The retrieved value is in the #AABBGGRR format, we need to - // convert it to the #AARRGGBB format that Qt accepts. + // convert it to the #AARRGGBB format which Qt expects. const QColor abgr = QColor::fromRgba(qvariant_cast(value)); if (!abgr.isValid()) { return alternative; diff --git a/src/quick/framelessquickutils.cpp b/src/quick/framelessquickutils.cpp index 7cee918..8bdbf30 100644 --- a/src/quick/framelessquickutils.cpp +++ b/src/quick/framelessquickutils.cpp @@ -94,15 +94,7 @@ void FramelessQuickUtils::setOverrideTheme(const QuickGlobal::SystemTheme theme) QColor FramelessQuickUtils::systemAccentColor() const { -#ifdef Q_OS_WINDOWS - return Utils::getDwmAccentColor(); -#elif defined(Q_OS_LINUX) - return Utils::getWmThemeColor(); -#elif defined(Q_OS_MACOS) - return Utils::getControlsAccentColor(); -#else - return {}; -#endif + return Utils::getAccentColor(); } bool FramelessQuickUtils::titleBarColorized() const