From 34596db939cf188f26e240963a637fbae3294030 Mon Sep 17 00:00:00 2001 From: Yuhang Zhao <2546789017@qq.com> Date: Sat, 10 Sep 2022 13:11:55 +0800 Subject: [PATCH] fix various issues found by user Issue list: 1. MinGW lacks some definitions so there's compilation errors 2. The chrome buttons' foreground color is incorrect when the window is inactive. 3. Adapt to new macros from Qt dev branch. 4. Remove unneeded parameter from setApplicationOSThemeAware(). Signed-off-by: Yuhang Zhao <2546789017@qq.com> --- examples/dialog/main.cpp | 2 +- examples/mainwindow/main.cpp | 2 +- examples/openglwidget/main.cpp | 2 +- examples/quick/main.cpp | 2 +- examples/widget/main.cpp | 2 +- .../Core/framelesshelper_windows.h | 13 ++- .../Core/framelesshelpercore_global.h | 2 +- include/FramelessHelper/Core/utils.h | 2 +- .../private/quickstandardsystembutton_p.h | 18 ++-- .../Widgets/private/standardsystembutton_p.h | 12 ++- .../Widgets/standardsystembutton.h | 16 +++- src/core/cmakehelper.cmake | 5 +- src/core/framelesshelper_qt.cpp | 3 +- src/core/framelesshelper_win.cpp | 14 ++- src/core/framelesshelpercore_global.cpp | 6 +- src/core/utils_win.cpp | 25 ++--- src/quick/quickstandardsystembutton.cpp | 82 +++++++++++------ src/quick/quickstandardtitlebar.cpp | 19 ++-- src/widgets/standardsystembutton.cpp | 92 ++++++++++++++++--- src/widgets/standardtitlebar.cpp | 18 ++-- 20 files changed, 232 insertions(+), 105 deletions(-) diff --git a/examples/dialog/main.cpp b/examples/dialog/main.cpp index 3324c31..a4e8609 100644 --- a/examples/dialog/main.cpp +++ b/examples/dialog/main.cpp @@ -42,7 +42,7 @@ int main(int argc, char *argv[]) // Must be called after QGuiApplication has been constructed, we are using // some private functions from QPA which won't be available until there's // a QGuiApplication instance. - FramelessHelper::Core::setApplicationOSThemeAware(false); + FramelessHelper::Core::setApplicationOSThemeAware(); FramelessConfig::instance()->set(Global::Option::WindowUseRoundCorners); FramelessConfig::instance()->set(Global::Option::EnableBlurBehindWindow); diff --git a/examples/mainwindow/main.cpp b/examples/mainwindow/main.cpp index 6d12087..727ff5b 100644 --- a/examples/mainwindow/main.cpp +++ b/examples/mainwindow/main.cpp @@ -42,7 +42,7 @@ int main(int argc, char *argv[]) // Must be called after QGuiApplication has been constructed, we are using // some private functions from QPA which won't be available until there's // a QGuiApplication instance. - FramelessHelper::Core::setApplicationOSThemeAware(false); + FramelessHelper::Core::setApplicationOSThemeAware(); FramelessConfig::instance()->set(Global::Option::WindowUseRoundCorners); FramelessConfig::instance()->set(Global::Option::EnableBlurBehindWindow); diff --git a/examples/openglwidget/main.cpp b/examples/openglwidget/main.cpp index 276a439..a5b66f4 100644 --- a/examples/openglwidget/main.cpp +++ b/examples/openglwidget/main.cpp @@ -79,7 +79,7 @@ int main(int argc, char *argv[]) // Must be called after QGuiApplication has been constructed, we are using // some private functions from QPA which won't be available until there's // a QGuiApplication instance. - FramelessHelper::Core::setApplicationOSThemeAware(false); + FramelessHelper::Core::setApplicationOSThemeAware(); FramelessConfig::instance()->set(Global::Option::WindowUseRoundCorners); FramelessConfig::instance()->set(Global::Option::EnableBlurBehindWindow); diff --git a/examples/quick/main.cpp b/examples/quick/main.cpp index 1eedddb..78f64a3 100644 --- a/examples/quick/main.cpp +++ b/examples/quick/main.cpp @@ -54,7 +54,7 @@ int main(int argc, char *argv[]) // Must be called after QGuiApplication has been constructed, we are using // some private functions from QPA which won't be available until there's // a QGuiApplication instance. - FramelessHelper::Core::setApplicationOSThemeAware(true); + FramelessHelper::Core::setApplicationOSThemeAware(); FramelessConfig::instance()->set(Global::Option::WindowUseRoundCorners); FramelessConfig::instance()->set(Global::Option::EnableBlurBehindWindow); diff --git a/examples/widget/main.cpp b/examples/widget/main.cpp index 95f9aaf..b1059ec 100644 --- a/examples/widget/main.cpp +++ b/examples/widget/main.cpp @@ -42,7 +42,7 @@ int main(int argc, char *argv[]) // Must be called after QGuiApplication has been constructed, we are using // some private functions from QPA which won't be available until there's // a QGuiApplication instance. - FramelessHelper::Core::setApplicationOSThemeAware(false); + FramelessHelper::Core::setApplicationOSThemeAware(); FramelessConfig::instance()->set(Global::Option::WindowUseRoundCorners); FramelessConfig::instance()->set(Global::Option::EnableBlurBehindWindow); diff --git a/include/FramelessHelper/Core/framelesshelper_windows.h b/include/FramelessHelper/Core/framelesshelper_windows.h index efd1337..bd42cd9 100644 --- a/include/FramelessHelper/Core/framelesshelper_windows.h +++ b/include/FramelessHelper/Core/framelesshelper_windows.h @@ -157,11 +157,22 @@ # define STATUS_SUCCESS (static_cast(0x00000000L)) #endif +#ifndef EXTERN_C +# define EXTERN_C extern "C" +#endif + +#ifndef EXTERN_C_START +# define EXTERN_C_START EXTERN_C { +#endif + +#ifndef EXTERN_C_END +# define EXTERN_C_END } +#endif + using NTSTATUS = LONG; #ifndef WINMMAPI using MMRESULT = UINT; - using TIMECAPS = struct TIMECAPS { UINT wPeriodMin; // minimum period supported diff --git a/include/FramelessHelper/Core/framelesshelpercore_global.h b/include/FramelessHelper/Core/framelesshelpercore_global.h index 4d33f1a..d6a95d3 100644 --- a/include/FramelessHelper/Core/framelesshelpercore_global.h +++ b/include/FramelessHelper/Core/framelesshelpercore_global.h @@ -579,7 +579,7 @@ FRAMELESSHELPER_CORE_API void uninitialize(); [[nodiscard]] FRAMELESSHELPER_CORE_API Global::VersionInfo version(); FRAMELESSHELPER_CORE_API void registerInitializeHook(const Global::InitializeHookCallback &cb); FRAMELESSHELPER_CORE_API void registerUninitializeHook(const Global::UninitializeHookCallback &cb); -FRAMELESSHELPER_CORE_API void setApplicationOSThemeAware(const bool pureQuick); +FRAMELESSHELPER_CORE_API void setApplicationOSThemeAware(); } // namespace FramelessHelper::Core FRAMELESSHELPER_END_NAMESPACE diff --git a/include/FramelessHelper/Core/utils.h b/include/FramelessHelper/Core/utils.h index 0aa71ea..9397784 100644 --- a/include/FramelessHelper/Core/utils.h +++ b/include/FramelessHelper/Core/utils.h @@ -116,7 +116,7 @@ FRAMELESSHELPER_CORE_API void forceSquareCornersForWindow(const WId windowId, co [[nodiscard]] FRAMELESSHELPER_CORE_API QColor getDwmAccentColor(); FRAMELESSHELPER_CORE_API void disableOriginalTitleBarFunctionalities (const WId windowId, const bool disable = true); -FRAMELESSHELPER_CORE_API void setQtDarkModeAwareEnabled(const bool enable, const bool pureQuick); +FRAMELESSHELPER_CORE_API void setQtDarkModeAwareEnabled(const bool enable); #endif // Q_OS_WINDOWS #ifdef Q_OS_LINUX diff --git a/include/FramelessHelper/Quick/private/quickstandardsystembutton_p.h b/include/FramelessHelper/Quick/private/quickstandardsystembutton_p.h index 07eae62..e4ad27b 100644 --- a/include/FramelessHelper/Quick/private/quickstandardsystembutton_p.h +++ b/include/FramelessHelper/Quick/private/quickstandardsystembutton_p.h @@ -47,7 +47,8 @@ class FRAMELESSHELPER_QUICK_API QuickStandardSystemButton : public QQuickButton Q_PROPERTY(QColor hoverColor READ hoverColor WRITE setHoverColor NOTIFY hoverColorChanged FINAL) Q_PROPERTY(QColor pressColor READ pressColor WRITE setPressColor NOTIFY pressColorChanged FINAL) Q_PROPERTY(QColor normalColor READ normalColor WRITE setNormalColor NOTIFY normalColorChanged FINAL) - Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged FINAL) + Q_PROPERTY(QColor activeForegroundColor READ activeForegroundColor WRITE setActiveForegroundColor NOTIFY activeForegroundColorChanged FINAL) + Q_PROPERTY(QColor inactiveForegroundColor READ inactiveForegroundColor WRITE setInactiveForegroundColor NOTIFY inactiveForegroundColorChanged FINAL) public: explicit QuickStandardSystemButton(QQuickItem *parent = nullptr); @@ -56,20 +57,21 @@ public: Q_NODISCARD QuickGlobal::SystemButtonType buttonType() const; Q_NODISCARD QString code() const; - Q_NODISCARD QColor color() const; Q_NODISCARD QColor normalColor() const; Q_NODISCARD QColor hoverColor() const; Q_NODISCARD QColor pressColor() const; + Q_NODISCARD QColor activeForegroundColor() const; + Q_NODISCARD QColor inactiveForegroundColor() const; public Q_SLOTS: - void updateForeground(); - void updateBackground(); + void updateColor(); void setButtonType(const QuickGlobal::SystemButtonType type); void setCode(const QString &value); - void setColor(const QColor &value); void setNormalColor(const QColor &value); void setHoverColor(const QColor &value); void setPressColor(const QColor &value); + void setActiveForegroundColor(const QColor &value); + void setInactiveForegroundColor(const QColor &value); private: void initialize(); @@ -77,20 +79,22 @@ private: Q_SIGNALS: void buttonTypeChanged(); void codeChanged(); - void colorChanged(); void normalColorChanged(); void hoverColorChanged(); void pressColorChanged(); + void activeForegroundColorChanged(); + void inactiveForegroundColorChanged(); private: QScopedPointer m_contentItem; QScopedPointer m_backgroundItem; QuickGlobal::SystemButtonType m_buttonType = QuickGlobal::SystemButtonType::Unknown; QString m_code = {}; - QColor m_color = {}; QColor m_normalColor = {}; QColor m_hoverColor = {}; QColor m_pressColor = {}; + QColor m_activeForegroundColor = {}; + QColor m_inactiveForegroundColor = {}; }; FRAMELESSHELPER_END_NAMESPACE diff --git a/include/FramelessHelper/Widgets/private/standardsystembutton_p.h b/include/FramelessHelper/Widgets/private/standardsystembutton_p.h index d60c493..4fc440e 100644 --- a/include/FramelessHelper/Widgets/private/standardsystembutton_p.h +++ b/include/FramelessHelper/Widgets/private/standardsystembutton_p.h @@ -62,14 +62,18 @@ public: Q_NODISCARD QColor getHoverColor() const; Q_NODISCARD QColor getPressColor() const; Q_NODISCARD QColor getNormalColor() const; - Q_NODISCARD QColor getColor() const; + Q_NODISCARD QColor getActiveForegroundColor() const; + Q_NODISCARD QColor getInactiveForegroundColor() const; + Q_NODISCARD bool isActive() const; void setHovered(const bool value); void setPressed(const bool value); void setHoverColor(const QColor &value); void setPressColor(const QColor &value); void setNormalColor(const QColor &value); - void setColor(const QColor &value); + void setActiveForegroundColor(const QColor &value); + void setInactiveForegroundColor(const QColor &value); + void setActive(const bool value); void enterEventHandler(QT_ENTER_EVENT_TYPE *event); void leaveEventHandler(QEvent *event); @@ -85,9 +89,11 @@ private: QColor m_hoverColor = {}; QColor m_pressColor = {}; QColor m_normalColor = {}; - QColor m_color = {}; + QColor m_activeForegroundColor = {}; + QColor m_inactiveForegroundColor = {}; bool m_hovered = false; bool m_pressed = false; + bool m_active = false; }; FRAMELESSHELPER_END_NAMESPACE diff --git a/include/FramelessHelper/Widgets/standardsystembutton.h b/include/FramelessHelper/Widgets/standardsystembutton.h index 76c37b6..f2f6401 100644 --- a/include/FramelessHelper/Widgets/standardsystembutton.h +++ b/include/FramelessHelper/Widgets/standardsystembutton.h @@ -46,7 +46,9 @@ class FRAMELESSHELPER_WIDGETS_API StandardSystemButton : public QAbstractButton Q_PROPERTY(QColor hoverColor READ hoverColor WRITE setHoverColor NOTIFY hoverColorChanged FINAL) Q_PROPERTY(QColor pressColor READ pressColor WRITE setPressColor NOTIFY pressColorChanged FINAL) Q_PROPERTY(QColor normalColor READ normalColor WRITE setNormalColor NOTIFY normalColorChanged FINAL) - Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged FINAL) + Q_PROPERTY(QColor activeForegroundColor READ activeForegroundColor WRITE setActiveForegroundColor NOTIFY activeForegroundColorChanged FINAL) + Q_PROPERTY(QColor inactiveForegroundColor READ inactiveForegroundColor WRITE setInactiveForegroundColor NOTIFY inactiveForegroundColorChanged FINAL) + Q_PROPERTY(bool active READ isActive WRITE setActive NOTIFY activeChanged FINAL) public: explicit StandardSystemButton(QWidget *parent = nullptr); @@ -61,7 +63,9 @@ public: Q_NODISCARD QColor hoverColor() const; Q_NODISCARD QColor pressColor() const; Q_NODISCARD QColor normalColor() const; - Q_NODISCARD QColor color() const; + Q_NODISCARD QColor activeForegroundColor() const; + Q_NODISCARD QColor inactiveForegroundColor() const; + Q_NODISCARD bool isActive() const; public Q_SLOTS: void setButtonType(const Global::SystemButtonType value); @@ -71,7 +75,9 @@ public Q_SLOTS: void setHoverColor(const QColor &value); void setPressColor(const QColor &value); void setNormalColor(const QColor &value); - void setColor(const QColor &value); + void setActiveForegroundColor(const QColor &value); + void setInactiveForegroundColor(const QColor &value); + void setActive(const bool value); protected: void enterEvent(QT_ENTER_EVENT_TYPE *event) override; @@ -86,7 +92,9 @@ Q_SIGNALS: void hoverColorChanged(); void pressColorChanged(); void normalColorChanged(); - void colorChanged(); + void activeForegroundColorChanged(); + void inactiveForegroundColorChanged(); + void activeChanged(); private: QScopedPointer d_ptr; diff --git a/src/core/cmakehelper.cmake b/src/core/cmakehelper.cmake index 84be86e..62bff77 100644 --- a/src/core/cmakehelper.cmake +++ b/src/core/cmakehelper.cmake @@ -33,7 +33,10 @@ function(setup_compile_params arg_target) QT_NO_FOREACH QT_USE_QSTRINGBUILDER QT_DEPRECATED_WARNINGS - QT_DISABLE_DEPRECATED_BEFORE=0x060500 # Remember to bump it when new Qt version releases. + QT_DEPRECATED_WARNINGS_SINCE=0x070000 + QT_WARN_DEPRECATED_UP_TO=0x070000 # Since 6.5 + QT_DISABLE_DEPRECATED_BEFORE=0x070000 + QT_DISABLE_DEPRECATED_UP_TO=0x070000 # Since 6.5 ) if(MSVC) set(_WIN32_WINNT_WIN10 0x0A00) diff --git a/src/core/framelesshelper_qt.cpp b/src/core/framelesshelper_qt.cpp index eaf260d..5885773 100644 --- a/src/core/framelesshelper_qt.cpp +++ b/src/core/framelesshelper_qt.cpp @@ -100,8 +100,7 @@ void FramelessHelperQt::addWindow(const SystemParameters ¶ms) #ifdef Q_OS_MACOS Utils::setSystemTitleBarVisible(windowId, false); #endif - static const bool isQtQuickApplication = (params.getCurrentApplicationType() == ApplicationType::Quick); - FramelessHelper::Core::setApplicationOSThemeAware(isQtQuickApplication); + FramelessHelper::Core::setApplicationOSThemeAware(); } bool FramelessHelperQt::eventFilter(QObject *object, QEvent *event) diff --git a/src/core/framelesshelper_win.cpp b/src/core/framelesshelper_win.cpp index bd1290c..7ce2574 100644 --- a/src/core/framelesshelper_win.cpp +++ b/src/core/framelesshelper_win.cpp @@ -422,7 +422,7 @@ Q_GLOBAL_STATIC(Win32Helper, g_win32Helper) const auto hwnd = reinterpret_cast(it.key()); Q_ASSERT(hwnd); if (hwnd && (DestroyWindow(hwnd) == FALSE)) { - WARNING << Utils::getSystemErrorMessage(kDestroyWindow); + //WARNING << Utils::getSystemErrorMessage(kDestroyWindow); } ++it; } @@ -431,11 +431,11 @@ Q_GLOBAL_STATIC(Win32Helper, g_win32Helper) g_win32Helper()->mutex.unlock(); const HINSTANCE instance = GetModuleHandleW(nullptr); if (!instance) { - WARNING << Utils::getSystemErrorMessage(kGetModuleHandleW); + //WARNING << Utils::getSystemErrorMessage(kGetModuleHandleW); return; } if (UnregisterClassW(kFallbackTitleBarWindowClassName, instance) == FALSE) { - WARNING << Utils::getSystemErrorMessage(kUnregisterClassW); + //WARNING << Utils::getSystemErrorMessage(kUnregisterClassW); } }); return true; @@ -499,8 +499,6 @@ void FramelessHelperWin::addWindow(const SystemParameters ¶ms) g_win32Helper()->mutex.unlock(); // Some Qt internals have to be corrected. Utils::fixupQtInternals(windowId); - // Tell DWM we don't need the window caption and window icon, don't draw them for us. - Utils::disableOriginalTitleBarFunctionalities(windowId); // Qt maintains a frame margin internally, we need to update it accordingly // otherwise we'll get lots of warning messages when we change the window // geometry, it will also affect the final window geometry because QPA will @@ -510,13 +508,13 @@ void FramelessHelperWin::addWindow(const SystemParameters ¶ms) Utils::updateWindowFrameMargins(windowId, false); static const bool isWin10RS1OrGreater = Utils::isWindowsVersionOrGreater(WindowsVersion::_10_1607); if (isWin10RS1OrGreater) { - const bool dark = Utils::shouldAppsUseDarkMode(); - static const bool isQtQuickApplication = (params.getCurrentApplicationType() == ApplicationType::Quick); // Tell DWM we may need dark theme non-client area (title bar & frame border). - FramelessHelper::Core::setApplicationOSThemeAware(isQtQuickApplication); + FramelessHelper::Core::setApplicationOSThemeAware(); + const bool dark = Utils::shouldAppsUseDarkMode(); Utils::updateWindowFrameBorderColor(windowId, dark); static const bool isWin10RS5OrGreater = Utils::isWindowsVersionOrGreater(WindowsVersion::_10_1809); if (isWin10RS5OrGreater) { + static const bool isQtQuickApplication = (params.getCurrentApplicationType() == ApplicationType::Quick); if (isQtQuickApplication) { // Tell UXTheme we may need dark theme controls. // Causes some QtWidgets paint incorrectly, so only apply to Qt Quick applications. diff --git a/src/core/framelesshelpercore_global.cpp b/src/core/framelesshelpercore_global.cpp index e23a24b..c2e72c0 100644 --- a/src/core/framelesshelpercore_global.cpp +++ b/src/core/framelesshelpercore_global.cpp @@ -271,7 +271,7 @@ void registerUninitializeHook(const UninitializeHookCallback &cb) coreData()->uninitHooks.append(cb); } -void setApplicationOSThemeAware(const bool pureQuick) +void setApplicationOSThemeAware() { static bool set = false; if (set) { @@ -280,9 +280,7 @@ void setApplicationOSThemeAware(const bool pureQuick) set = true; #if (defined(Q_OS_WINDOWS) && (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))) - Utils::setQtDarkModeAwareEnabled(true, pureQuick); -#else - Q_UNUSED(pureQuick); + Utils::setQtDarkModeAwareEnabled(true); #endif #if ((defined(Q_OS_LINUX) && (QT_VERSION < QT_VERSION_CHECK(6, 4, 0))) || \ diff --git a/src/core/utils_win.cpp b/src/core/utils_win.cpp index b2d28e8..3d46558 100644 --- a/src/core/utils_win.cpp +++ b/src/core/utils_win.cpp @@ -286,16 +286,16 @@ private: } FramelessHelper::Core::registerUninitializeHook([window](){ if (window && (DestroyWindow(window) == FALSE)) { - WARNING << Utils::getSystemErrorMessage(kDestroyWindow); + //WARNING << Utils::getSystemErrorMessage(kDestroyWindow); return; } const HINSTANCE instance = GetModuleHandleW(nullptr); if (!instance) { - WARNING << Utils::getSystemErrorMessage(kGetModuleHandleW); + //WARNING << Utils::getSystemErrorMessage(kGetModuleHandleW); return; } if (UnregisterClassW(kDummyWindowClassName, instance) == FALSE) { - WARNING << Utils::getSystemErrorMessage(kUnregisterClassW); + //WARNING << Utils::getSystemErrorMessage(kUnregisterClassW); } }); return window; @@ -1785,6 +1785,7 @@ bool Utils::isBlurBehindWindowSupported() void Utils::disableOriginalTitleBarFunctionalities(const WId windowId, const bool disable) { +#if 0 Q_ASSERT(windowId); if (!windowId) { return; @@ -1802,9 +1803,13 @@ void Utils::disableOriginalTitleBarFunctionalities(const WId windowId, const boo if (FAILED(hr)) { WARNING << __getSystemErrorMessage(kSetWindowThemeAttribute, hr); } +#else + Q_UNUSED(windowId); + Q_UNUSED(disable); +#endif } -void Utils::setQtDarkModeAwareEnabled(const bool enable, const bool pureQuick) +void Utils::setQtDarkModeAwareEnabled(const bool enable) { #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) // We'll call QPA functions, so we have to ensure that the QGuiApplication @@ -1815,12 +1820,11 @@ void Utils::setQtDarkModeAwareEnabled(const bool enable, const bool pureQuick) } using App = QNativeInterface::Private::QWindowsApplication; if (const auto app = qApp->nativeInterface()) { - app->setDarkModeHandling([enable, pureQuick]() -> App::DarkModeHandling { + app->setDarkModeHandling([enable]() -> App::DarkModeHandling { if (!enable) { - return {}; + return {}; // Clear the flags. } #if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)) - Q_UNUSED(pureQuick); // Enabling the DarkModeWindowFrames flag will save us the call of the // DwmSetWindowAttribute function. Qt will adjust the non-client area // (title bar & frame border) automatically. @@ -1831,11 +1835,9 @@ void Utils::setQtDarkModeAwareEnabled(const bool enable, const bool pureQuick) // flag has no effect for pure Qt Quick applications. return {App::DarkModeWindowFrames | App::DarkModeStyle}; #else // (QT_VERSION < QT_VERSION_CHECK(6, 5, 0)) - if (pureQuick) { - // Pure Qt Quick application, it's OK to enable the DarkModeStyle flag. - return {App::DarkModeWindowFrames | App::DarkModeStyle}; - } // Don't try to use the broken dark theme for Qt Widgets applications. + // For Qt Quick applications this is also enough. There's no global dark + // theme for them anyway. return {App::DarkModeWindowFrames}; #endif // (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)) }()); @@ -1844,7 +1846,6 @@ void Utils::setQtDarkModeAwareEnabled(const bool enable, const bool pureQuick) } #else // (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) Q_UNUSED(enable); - Q_UNUSED(pureQuick); #endif // (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) } diff --git a/src/quick/quickstandardsystembutton.cpp b/src/quick/quickstandardsystembutton.cpp index e556edc..d71daff 100644 --- a/src/quick/quickstandardsystembutton.cpp +++ b/src/quick/quickstandardsystembutton.cpp @@ -26,6 +26,7 @@ #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) #include #include +#include #include #include #include @@ -64,11 +65,6 @@ QString QuickStandardSystemButton::code() const return m_code; } -QColor QuickStandardSystemButton::color() const -{ - return m_color; -} - QColor QuickStandardSystemButton::normalColor() const { return m_normalColor; @@ -84,6 +80,16 @@ QColor QuickStandardSystemButton::pressColor() const return m_pressColor; } +QColor QuickStandardSystemButton::activeForegroundColor() const +{ + return m_activeForegroundColor; +} + +QColor QuickStandardSystemButton::inactiveForegroundColor() const +{ + return m_inactiveForegroundColor; +} + void QuickStandardSystemButton::setButtonType(const QuickGlobal::SystemButtonType type) { Q_ASSERT(type != QuickGlobal::SystemButtonType::Unknown); @@ -113,20 +119,6 @@ void QuickStandardSystemButton::setCode(const QString &value) Q_EMIT codeChanged(); } -void QuickStandardSystemButton::setColor(const QColor &value) -{ - Q_ASSERT(value.isValid()); - if (!value.isValid()) { - return; - } - if (m_color == value) { - return; - } - m_color = value; - updateForeground(); - Q_EMIT colorChanged(); -} - void QuickStandardSystemButton::setNormalColor(const QColor &value) { Q_ASSERT(value.isValid()); @@ -137,7 +129,7 @@ void QuickStandardSystemButton::setNormalColor(const QColor &value) return; } m_normalColor = value; - updateBackground(); + updateColor(); Q_EMIT normalColorChanged(); } @@ -151,7 +143,7 @@ void QuickStandardSystemButton::setHoverColor(const QColor &value) return; } m_hoverColor = value; - updateBackground(); + updateColor(); Q_EMIT hoverColorChanged(); } @@ -165,19 +157,52 @@ void QuickStandardSystemButton::setPressColor(const QColor &value) return; } m_pressColor = value; - updateBackground(); + updateColor(); Q_EMIT pressColorChanged(); } -void QuickStandardSystemButton::updateForeground() +void QuickStandardSystemButton::setActiveForegroundColor(const QColor &value) { - m_contentItem->setColor(m_color.isValid() ? m_color : kDefaultBlackColor); + Q_ASSERT(value.isValid()); + if (!value.isValid()) { + return; + } + if (m_activeForegroundColor == value) { + return; + } + m_activeForegroundColor = value; + updateColor(); + Q_EMIT activeForegroundColorChanged(); } -void QuickStandardSystemButton::updateBackground() +void QuickStandardSystemButton::setInactiveForegroundColor(const QColor &value) +{ + Q_ASSERT(value.isValid()); + if (!value.isValid()) { + return; + } + if (m_inactiveForegroundColor == value) { + return; + } + m_inactiveForegroundColor = value; + updateColor(); + Q_EMIT inactiveForegroundColorChanged(); +} + +void QuickStandardSystemButton::updateColor() { const bool hover = isHovered(); const bool press = isPressed(); + m_contentItem->setColor([this, hover]() -> QColor { + const bool active = (window() ? window()->isActive() : false); + if (!hover && !active && m_inactiveForegroundColor.isValid()) { + return m_inactiveForegroundColor; + } + if (m_activeForegroundColor.isValid()) { + return m_activeForegroundColor; + } + return kDefaultBlackColor; + }()); m_backgroundItem->setColor([this, hover, press]() -> QColor { if (press && m_pressColor.isValid()) { return m_pressColor; @@ -214,11 +239,10 @@ void QuickStandardSystemButton::initialize() QQuickPen * const border = m_backgroundItem->border(); border->setWidth(0.0); border->setColor(kDefaultTransparentColor); - connect(this, &QuickStandardSystemButton::hoveredChanged, this, &QuickStandardSystemButton::updateBackground); - connect(this, &QuickStandardSystemButton::pressedChanged, this, &QuickStandardSystemButton::updateBackground); + connect(this, &QuickStandardSystemButton::hoveredChanged, this, &QuickStandardSystemButton::updateColor); + connect(this, &QuickStandardSystemButton::pressedChanged, this, &QuickStandardSystemButton::updateColor); - updateBackground(); - updateForeground(); + updateColor(); setContentItem(m_contentItem.data()); setBackground(m_backgroundItem.data()); diff --git a/src/quick/quickstandardtitlebar.cpp b/src/quick/quickstandardtitlebar.cpp index c30558f..1ecad5a 100644 --- a/src/quick/quickstandardtitlebar.cpp +++ b/src/quick/quickstandardtitlebar.cpp @@ -263,26 +263,29 @@ void QuickStandardTitleBar::updateChromeButtonColor() if (!w) { return; } - const bool active = w->isActive(); - const QColor color = (active ? - m_chromePalette->titleBarActiveForegroundColor() : - m_chromePalette->titleBarInactiveForegroundColor()); + const QColor activeForeground = m_chromePalette->titleBarActiveForegroundColor(); + const QColor inactiveForeground = m_chromePalette->titleBarInactiveForegroundColor(); const QColor normal = m_chromePalette->chromeButtonNormalColor(); const QColor hover = m_chromePalette->chromeButtonHoverColor(); const QColor press = m_chromePalette->chromeButtonPressColor(); - m_minimizeButton->setColor(color); + m_minimizeButton->setActiveForegroundColor(activeForeground); + m_minimizeButton->setInactiveForegroundColor(inactiveForeground); m_minimizeButton->setNormalColor(normal); m_minimizeButton->setHoverColor(hover); m_minimizeButton->setPressColor(press); - m_maximizeButton->setColor(color); + m_minimizeButton->updateColor(); + m_maximizeButton->setActiveForegroundColor(activeForeground); + m_maximizeButton->setInactiveForegroundColor(inactiveForeground); m_maximizeButton->setNormalColor(normal); m_maximizeButton->setHoverColor(hover); m_maximizeButton->setPressColor(press); - m_closeButton->setColor(color); - // The close button is special. + m_maximizeButton->updateColor(); + m_closeButton->setActiveForegroundColor(activeForeground); + m_closeButton->setInactiveForegroundColor(inactiveForeground); m_closeButton->setNormalColor(m_chromePalette->closeButtonNormalColor()); m_closeButton->setHoverColor(m_chromePalette->closeButtonHoverColor()); m_closeButton->setPressColor(m_chromePalette->closeButtonPressColor()); + m_closeButton->updateColor(); } void QuickStandardTitleBar::clickMinimizeButton() diff --git a/src/widgets/standardsystembutton.cpp b/src/widgets/standardsystembutton.cpp index f2779b4..5ef0951 100644 --- a/src/widgets/standardsystembutton.cpp +++ b/src/widgets/standardsystembutton.cpp @@ -141,9 +141,19 @@ QColor StandardSystemButtonPrivate::getNormalColor() const return m_normalColor; } -QColor StandardSystemButtonPrivate::getColor() const +QColor StandardSystemButtonPrivate::getActiveForegroundColor() const { - return m_color; + return m_activeForegroundColor; +} + +QColor StandardSystemButtonPrivate::getInactiveForegroundColor() const +{ + return m_inactiveForegroundColor; +} + +bool StandardSystemButtonPrivate::isActive() const +{ + return m_active; } void StandardSystemButtonPrivate::setHovered(const bool value) @@ -238,19 +248,45 @@ void StandardSystemButtonPrivate::setNormalColor(const QColor &value) Q_EMIT q->normalColorChanged(); } -void StandardSystemButtonPrivate::setColor(const QColor &value) +void StandardSystemButtonPrivate::setActiveForegroundColor(const QColor &value) { Q_ASSERT(value.isValid()); if (!value.isValid()) { return; } - if (m_color == value) { + if (m_activeForegroundColor == value) { return; } - m_color = value; + m_activeForegroundColor = value; Q_Q(StandardSystemButton); q->update(); - Q_EMIT q->colorChanged(); + Q_EMIT q->activeForegroundColorChanged(); +} + +void StandardSystemButtonPrivate::setInactiveForegroundColor(const QColor &value) +{ + Q_ASSERT(value.isValid()); + if (!value.isValid()) { + return; + } + if (m_inactiveForegroundColor == value) { + return; + } + m_inactiveForegroundColor = value; + Q_Q(StandardSystemButton); + q->update(); + Q_EMIT q->inactiveForegroundColorChanged(); +} + +void StandardSystemButtonPrivate::setActive(const bool value) +{ + if (m_active == value) { + return; + } + m_active = value; + Q_Q(StandardSystemButton); + q->update(); + Q_EMIT q->activeChanged(); } void StandardSystemButtonPrivate::enterEventHandler(QT_ENTER_EVENT_TYPE *event) @@ -298,8 +334,16 @@ void StandardSystemButtonPrivate::paintEventHandler(QPaintEvent *event) if (backgroundColor.isValid()) { painter.fillRect(g_buttonRect, backgroundColor); } - if (!m_code.isEmpty() && m_color.isValid()) { - painter.setPen(m_color); + if (!m_code.isEmpty()) { + painter.setPen([this]() -> QColor { + if (!m_hovered && !m_active && m_inactiveForegroundColor.isValid()) { + return m_inactiveForegroundColor; + } + if (m_activeForegroundColor.isValid()) { + return m_activeForegroundColor; + } + return kDefaultBlackColor; + }()); painter.setFont(FramelessManagerPrivate::getIconFont()); painter.drawText(g_buttonRect, Qt::AlignCenter, m_code); } @@ -406,10 +450,22 @@ QColor StandardSystemButton::normalColor() const return d->getNormalColor(); } -QColor StandardSystemButton::color() const +QColor StandardSystemButton::activeForegroundColor() const { Q_D(const StandardSystemButton); - return d->getColor(); + return d->getActiveForegroundColor(); +} + +QColor StandardSystemButton::inactiveForegroundColor() const +{ + Q_D(const StandardSystemButton); + return d->getInactiveForegroundColor(); +} + +bool StandardSystemButton::isActive() const +{ + Q_D(const StandardSystemButton); + return d->isActive(); } void StandardSystemButton::setPressColor(const QColor &value) @@ -424,10 +480,22 @@ void StandardSystemButton::setNormalColor(const QColor &value) d->setNormalColor(value); } -void StandardSystemButton::setColor(const QColor &value) +void StandardSystemButton::setActiveForegroundColor(const QColor &value) { Q_D(StandardSystemButton); - d->setColor(value); + d->setActiveForegroundColor(value); +} + +void StandardSystemButton::setInactiveForegroundColor(const QColor &value) +{ + Q_D(StandardSystemButton); + d->setInactiveForegroundColor(value); +} + +void StandardSystemButton::setActive(const bool value) +{ + Q_D(StandardSystemButton); + d->setActive(value); } void StandardSystemButton::enterEvent(QT_ENTER_EVENT_TYPE *event) diff --git a/src/widgets/standardtitlebar.cpp b/src/widgets/standardtitlebar.cpp index 40b3f3d..0b3e35e 100644 --- a/src/widgets/standardtitlebar.cpp +++ b/src/widgets/standardtitlebar.cpp @@ -266,25 +266,29 @@ void StandardTitleBarPrivate::updateTitleBarColor() void StandardTitleBarPrivate::updateChromeButtonColor() { const bool active = m_window->isActiveWindow(); - const QColor color = (active ? - m_chromePalette->titleBarActiveForegroundColor() : - m_chromePalette->titleBarInactiveForegroundColor()); + const QColor activeForeground = m_chromePalette->titleBarActiveForegroundColor(); + const QColor inactiveForeground = m_chromePalette->titleBarInactiveForegroundColor(); const QColor normal = m_chromePalette->chromeButtonNormalColor(); const QColor hover = m_chromePalette->chromeButtonHoverColor(); const QColor press = m_chromePalette->chromeButtonPressColor(); - m_minimizeButton->setColor(color); + m_minimizeButton->setActiveForegroundColor(activeForeground); + m_minimizeButton->setInactiveForegroundColor(inactiveForeground); m_minimizeButton->setNormalColor(normal); m_minimizeButton->setHoverColor(hover); m_minimizeButton->setPressColor(press); - m_maximizeButton->setColor(color); + m_minimizeButton->setActive(active); + m_maximizeButton->setActiveForegroundColor(activeForeground); + m_maximizeButton->setInactiveForegroundColor(inactiveForeground); m_maximizeButton->setNormalColor(normal); m_maximizeButton->setHoverColor(hover); m_maximizeButton->setPressColor(press); - m_closeButton->setColor(color); - // The close button is special. + m_maximizeButton->setActive(active); + m_closeButton->setActiveForegroundColor(activeForeground); + m_closeButton->setInactiveForegroundColor(inactiveForeground); m_closeButton->setNormalColor(m_chromePalette->closeButtonNormalColor()); m_closeButton->setHoverColor(m_chromePalette->closeButtonHoverColor()); m_closeButton->setPressColor(m_chromePalette->closeButtonPressColor()); + m_closeButton->setActive(active); } void StandardTitleBarPrivate::retranslateUi()