general: fix the system button background color in various cases

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
This commit is contained in:
Yuhang Zhao 2022-05-12 17:25:10 +08:00
parent 8cb24c61b3
commit 5c3b8b70df
10 changed files with 151 additions and 20 deletions

View File

@ -47,17 +47,22 @@ public:
explicit QuickStandardCloseButton(QQuickItem *parent = nullptr); explicit QuickStandardCloseButton(QQuickItem *parent = nullptr);
~QuickStandardCloseButton() override; ~QuickStandardCloseButton() override;
private Q_SLOTS: public Q_SLOTS:
void updateForeground(); void updateForeground();
void updateBackground(); void updateBackground();
void setInactive(const bool value);
private: private:
void initialize(); void initialize();
void checkInactive();
private: private:
QScopedPointer<QQuickItem> m_contentItem; QScopedPointer<QQuickItem> m_contentItem;
QScopedPointer<QQuickImage> m_image; QScopedPointer<QQuickImage> m_image;
QScopedPointer<QQuickRectangle> m_backgroundItem; QScopedPointer<QQuickRectangle> m_backgroundItem;
bool m_forceLightTheme = false;
bool m_shouldCheck = false;
bool m_checkFlag = false;
}; };
FRAMELESSHELPER_END_NAMESPACE FRAMELESSHELPER_END_NAMESPACE

View File

@ -51,21 +51,26 @@ public:
Q_NODISCARD bool isMaximized() const; Q_NODISCARD bool isMaximized() const;
void setMaximized(const bool max); void setMaximized(const bool max);
private Q_SLOTS: public Q_SLOTS:
void updateForeground(); void updateForeground();
void updateBackground(); void updateBackground();
void setInactive(const bool value);
Q_SIGNALS: Q_SIGNALS:
void maximizedChanged(); void maximizedChanged();
private: private:
void initialize(); void initialize();
void checkInactive();
private: private:
bool m_max = false; bool m_max = false;
QScopedPointer<QQuickItem> m_contentItem; QScopedPointer<QQuickItem> m_contentItem;
QScopedPointer<QQuickImage> m_image; QScopedPointer<QQuickImage> m_image;
QScopedPointer<QQuickRectangle> m_backgroundItem; QScopedPointer<QQuickRectangle> m_backgroundItem;
bool m_forceLightTheme = false;
bool m_shouldCheck = false;
bool m_checkFlag = false;
}; };
FRAMELESSHELPER_END_NAMESPACE FRAMELESSHELPER_END_NAMESPACE

View File

@ -47,17 +47,22 @@ public:
explicit QuickStandardMinimizeButton(QQuickItem *parent = nullptr); explicit QuickStandardMinimizeButton(QQuickItem *parent = nullptr);
~QuickStandardMinimizeButton() override; ~QuickStandardMinimizeButton() override;
private Q_SLOTS: public Q_SLOTS:
void updateForeground(); void updateForeground();
void updateBackground(); void updateBackground();
void setInactive(const bool value);
private: private:
void initialize(); void initialize();
void checkInactive();
private: private:
QScopedPointer<QQuickItem> m_contentItem; QScopedPointer<QQuickItem> m_contentItem;
QScopedPointer<QQuickImage> m_image; QScopedPointer<QQuickImage> m_image;
QScopedPointer<QQuickRectangle> m_backgroundItem; QScopedPointer<QQuickRectangle> m_backgroundItem;
bool m_forceLightTheme = false;
bool m_shouldCheck = false;
bool m_checkFlag = false;
}; };
FRAMELESSHELPER_END_NAMESPACE FRAMELESSHELPER_END_NAMESPACE

View File

@ -75,8 +75,11 @@ public:
void leaveEventHandler(QEvent *event); void leaveEventHandler(QEvent *event);
void paintEventHandler(QPaintEvent *event); void paintEventHandler(QPaintEvent *event);
void setInactive(const bool value);
private: private:
void initialize(); void initialize();
void checkInactive();
private: private:
StandardSystemButton *q_ptr = nullptr; StandardSystemButton *q_ptr = nullptr;
@ -88,6 +91,9 @@ private:
QColor m_pressColor = {}; QColor m_pressColor = {};
bool m_hovered = false; bool m_hovered = false;
bool m_pressed = false; bool m_pressed = false;
bool m_forceLightTheme = false;
bool m_shouldCheck = false;
bool m_checkFlag = false;
}; };
FRAMELESSHELPER_END_NAMESPACE FRAMELESSHELPER_END_NAMESPACE

View File

@ -52,7 +52,7 @@ QuickStandardCloseButton::~QuickStandardCloseButton() = default;
void QuickStandardCloseButton::updateForeground() void QuickStandardCloseButton::updateForeground()
{ {
const bool dark = (Utils::shouldAppsUseDarkMode() || Utils::isTitleBarColorized()); const bool dark = ((Utils::shouldAppsUseDarkMode() || Utils::isTitleBarColorized()) && !m_forceLightTheme);
const auto url = QUrl((dark || isHovered() || isPressed()) ? kDarkUrl : kLightUrl); const auto url = QUrl((dark || isHovered() || isPressed()) ? kDarkUrl : kLightUrl);
initResource(); initResource();
m_image->setSource(url); m_image->setSource(url);
@ -65,9 +65,31 @@ void QuickStandardCloseButton::updateBackground()
const bool press = isPressed(); const bool press = isPressed();
m_backgroundItem->setColor(Utils::calculateSystemButtonBackgroundColor(button, (press ? ButtonState::Pressed : ButtonState::Hovered))); m_backgroundItem->setColor(Utils::calculateSystemButtonBackgroundColor(button, (press ? ButtonState::Pressed : ButtonState::Hovered)));
m_backgroundItem->setVisible(hover || press); m_backgroundItem->setVisible(hover || press);
checkInactive();
qobject_cast<QQuickToolTipAttached *>(qmlAttachedPropertiesObject<QQuickToolTip>(this))->setVisible(hover); qobject_cast<QQuickToolTipAttached *>(qmlAttachedPropertiesObject<QQuickToolTip>(this))->setVisible(hover);
} }
void QuickStandardCloseButton::setInactive(const bool value)
{
const bool force = (value && Utils::isTitleBarColorized() && !Utils::shouldAppsUseDarkMode());
if (m_forceLightTheme == force) {
return;
}
m_forceLightTheme = force;
m_shouldCheck = m_forceLightTheme;
updateForeground();
}
void QuickStandardCloseButton::checkInactive()
{
if (!m_shouldCheck) {
return;
}
m_forceLightTheme = m_checkFlag;
m_checkFlag = !m_checkFlag;
updateForeground();
}
void QuickStandardCloseButton::initialize() void QuickStandardCloseButton::initialize()
{ {
setImplicitWidth(kDefaultSystemButtonSize.width()); setImplicitWidth(kDefaultSystemButtonSize.width());

View File

@ -68,7 +68,7 @@ void QuickStandardMaximizeButton::setMaximized(const bool max)
void QuickStandardMaximizeButton::updateForeground() void QuickStandardMaximizeButton::updateForeground()
{ {
const bool dark = (Utils::shouldAppsUseDarkMode() || Utils::isTitleBarColorized()); const bool dark = ((Utils::shouldAppsUseDarkMode() || Utils::isTitleBarColorized()) && !m_forceLightTheme);
const auto url = QUrl(dark ? (m_max ? kDarkRestoreUrl : kDarkMaxUrl) : (m_max ? kLightRestoreUrl : kLightMaxUrl)); const auto url = QUrl(dark ? (m_max ? kDarkRestoreUrl : kDarkMaxUrl) : (m_max ? kLightRestoreUrl : kLightMaxUrl));
initResource(); initResource();
m_image->setSource(url); m_image->setSource(url);
@ -81,9 +81,31 @@ void QuickStandardMaximizeButton::updateBackground()
const bool press = isPressed(); const bool press = isPressed();
m_backgroundItem->setColor(Utils::calculateSystemButtonBackgroundColor(button, (press ? ButtonState::Pressed : ButtonState::Hovered))); m_backgroundItem->setColor(Utils::calculateSystemButtonBackgroundColor(button, (press ? ButtonState::Pressed : ButtonState::Hovered)));
m_backgroundItem->setVisible(hover || press); m_backgroundItem->setVisible(hover || press);
checkInactive();
qobject_cast<QQuickToolTipAttached *>(qmlAttachedPropertiesObject<QQuickToolTip>(this))->setVisible(hover); qobject_cast<QQuickToolTipAttached *>(qmlAttachedPropertiesObject<QQuickToolTip>(this))->setVisible(hover);
} }
void QuickStandardMaximizeButton::setInactive(const bool value)
{
const bool force = (value && Utils::isTitleBarColorized() && !Utils::shouldAppsUseDarkMode());
if (m_forceLightTheme == force) {
return;
}
m_forceLightTheme = force;
m_shouldCheck = m_forceLightTheme;
updateForeground();
}
void QuickStandardMaximizeButton::checkInactive()
{
if (!m_shouldCheck) {
return;
}
m_forceLightTheme = m_checkFlag;
m_checkFlag = !m_checkFlag;
updateForeground();
}
void QuickStandardMaximizeButton::initialize() void QuickStandardMaximizeButton::initialize()
{ {
setImplicitWidth(kDefaultSystemButtonSize.width()); setImplicitWidth(kDefaultSystemButtonSize.width());

View File

@ -52,7 +52,7 @@ QuickStandardMinimizeButton::~QuickStandardMinimizeButton() = default;
void QuickStandardMinimizeButton::updateForeground() void QuickStandardMinimizeButton::updateForeground()
{ {
const bool dark = (Utils::shouldAppsUseDarkMode() || Utils::isTitleBarColorized()); const bool dark = ((Utils::shouldAppsUseDarkMode() || Utils::isTitleBarColorized()) && !m_forceLightTheme);
const auto url = QUrl(dark ? kDarkUrl : kLightUrl); const auto url = QUrl(dark ? kDarkUrl : kLightUrl);
initResource(); initResource();
m_image->setSource(url); m_image->setSource(url);
@ -65,9 +65,31 @@ void QuickStandardMinimizeButton::updateBackground()
const bool press = isPressed(); const bool press = isPressed();
m_backgroundItem->setColor(Utils::calculateSystemButtonBackgroundColor(button, (press ? ButtonState::Pressed : ButtonState::Hovered))); m_backgroundItem->setColor(Utils::calculateSystemButtonBackgroundColor(button, (press ? ButtonState::Pressed : ButtonState::Hovered)));
m_backgroundItem->setVisible(hover || press); m_backgroundItem->setVisible(hover || press);
checkInactive();
qobject_cast<QQuickToolTipAttached *>(qmlAttachedPropertiesObject<QQuickToolTip>(this))->setVisible(hover); qobject_cast<QQuickToolTipAttached *>(qmlAttachedPropertiesObject<QQuickToolTip>(this))->setVisible(hover);
} }
void QuickStandardMinimizeButton::setInactive(const bool value)
{
const bool force = (value && Utils::isTitleBarColorized() && !Utils::shouldAppsUseDarkMode());
if (m_forceLightTheme == force) {
return;
}
m_forceLightTheme = force;
m_shouldCheck = m_forceLightTheme;
updateForeground();
}
void QuickStandardMinimizeButton::checkInactive()
{
if (!m_shouldCheck) {
return;
}
m_forceLightTheme = m_checkFlag;
m_checkFlag = !m_checkFlag;
updateForeground();
}
void QuickStandardMinimizeButton::initialize() void QuickStandardMinimizeButton::initialize()
{ {
setImplicitWidth(kDefaultSystemButtonSize.width()); setImplicitWidth(kDefaultSystemButtonSize.width());

View File

@ -155,9 +155,10 @@ void QuickStandardTitleBar::updateTitleBarColor()
if (!w) { if (!w) {
return; return;
} }
const bool active = w->isActive();
QColor backgroundColor = {}; QColor backgroundColor = {};
QColor foregroundColor = {}; QColor foregroundColor = {};
if (w->isActive()) { if (active) {
if (Utils::isTitleBarColorized()) { if (Utils::isTitleBarColorized()) {
#ifdef Q_OS_WINDOWS #ifdef Q_OS_WINDOWS
backgroundColor = Utils::getDwmColorizationColor(); backgroundColor = Utils::getDwmColorizationColor();
@ -188,6 +189,9 @@ void QuickStandardTitleBar::updateTitleBarColor()
} }
setColor(backgroundColor); setColor(backgroundColor);
m_windowTitleLabel->setColor(foregroundColor); m_windowTitleLabel->setColor(foregroundColor);
m_minimizeButton->setInactive(!active);
m_maximizeButton->setInactive(!active);
m_closeButton->setInactive(!active);
} }
void QuickStandardTitleBar::clickMinimizeButton() void QuickStandardTitleBar::clickMinimizeButton()

View File

@ -73,7 +73,10 @@ void StandardSystemButtonPrivate::refreshButtonTheme(const bool force)
if (m_buttonType == SystemButtonType::Unknown) { if (m_buttonType == SystemButtonType::Unknown) {
return; return;
} }
const SystemTheme systemTheme = []() -> SystemTheme { const SystemTheme systemTheme = [this]() -> SystemTheme {
if (m_forceLightTheme) {
return SystemTheme::Light;
}
#ifdef Q_OS_WINDOWS #ifdef Q_OS_WINDOWS
if (Utils::isTitleBarColorized()) { if (Utils::isTitleBarColorized()) {
return SystemTheme::Dark; return SystemTheme::Dark;
@ -204,7 +207,16 @@ void StandardSystemButtonPrivate::setHovered(const bool value)
if (m_hovered) { if (m_hovered) {
const QString toolTip = q->toolTip(); const QString toolTip = q->toolTip();
if (!toolTip.isEmpty() && !QToolTip::isVisible()) { if (!toolTip.isEmpty() && !QToolTip::isVisible()) {
QToolTip::showText(q->mapToGlobal(QPoint(0, -(qRound(qreal(q->height()) * 1.3)))), toolTip, q, q->geometry()); const int yPos = [q]() -> int {
const auto h = qreal(q->height());
if (const QWidget * const window = q->window()) {
if (Utils::windowStatesToWindowState(window->windowState()) == Qt::WindowMaximized) {
return int(qRound(h * 0.5));
}
}
return -int(qRound(h * 1.3));
}();
QToolTip::showText(q->mapToGlobal(QPoint(-2, yPos)), toolTip, q, q->geometry());
} }
} else { } else {
if (QToolTip::isVisible()) { if (QToolTip::isVisible()) {
@ -299,17 +311,40 @@ void StandardSystemButtonPrivate::paintEventHandler(QPaintEvent *event)
painter.fillRect(g_buttonRect, color); painter.fillRect(g_buttonRect, color);
} }
if (!m_icon.isNull()) { if (!m_icon.isNull()) {
painter.drawPixmap(g_buttonIconX, painter.drawPixmap(g_buttonIconX, g_buttonIconY, [this]() -> QPixmap {
g_buttonIconY, if (m_reversedIcon.isNull()) {
((m_buttonType == SystemButtonType::Close) return m_icon;
&& (m_buttonTheme == SystemTheme::Light) && m_hovered }
&& !m_reversedIcon.isNull()) if (m_hovered && m_forceLightTheme) {
? m_reversedIcon return m_reversedIcon;
: m_icon); }
return m_icon;
}());
} }
painter.restore(); painter.restore();
} }
void StandardSystemButtonPrivate::setInactive(const bool value)
{
const bool force = (value && Utils::isTitleBarColorized() && !Utils::shouldAppsUseDarkMode());
if (m_forceLightTheme == force) {
return;
}
m_forceLightTheme = force;
m_shouldCheck = m_forceLightTheme;
refreshButtonTheme(true);
}
void StandardSystemButtonPrivate::checkInactive()
{
if (!m_shouldCheck) {
return;
}
m_forceLightTheme = m_checkFlag;
m_checkFlag = !m_checkFlag;
refreshButtonTheme(true);
}
void StandardSystemButtonPrivate::initialize() void StandardSystemButtonPrivate::initialize()
{ {
Q_Q(StandardSystemButton); Q_Q(StandardSystemButton);

View File

@ -25,6 +25,7 @@
#include "standardtitlebar.h" #include "standardtitlebar.h"
#include "standardtitlebar_p.h" #include "standardtitlebar_p.h"
#include "standardsystembutton.h" #include "standardsystembutton.h"
#include "standardsystembutton_p.h"
#include <QtCore/qcoreevent.h> #include <QtCore/qcoreevent.h>
#include <QtGui/qpainter.h> #include <QtGui/qpainter.h>
#include <QtWidgets/qlabel.h> #include <QtWidgets/qlabel.h>
@ -84,13 +85,13 @@ void StandardTitleBarPrivate::setTitleLabelAlignment(const Qt::Alignment value)
m_labelAlignment = value; m_labelAlignment = value;
bool needsInvalidate = false; bool needsInvalidate = false;
if (m_labelAlignment & Qt::AlignLeft) { if (m_labelAlignment & Qt::AlignLeft) {
m_labelLeftStretch->changeSize(0, 0); m_labelLeftStretch->changeSize(kDefaultTitleBarContentsMargin, 0, QSizePolicy::Fixed);
m_labelRightStretch->changeSize(0, 0, QSizePolicy::Expanding); m_labelRightStretch->changeSize(0, 0, QSizePolicy::Expanding);
needsInvalidate = true; needsInvalidate = true;
} }
if (m_labelAlignment & Qt::AlignRight) { if (m_labelAlignment & Qt::AlignRight) {
m_labelLeftStretch->changeSize(0, 0, QSizePolicy::Expanding); m_labelLeftStretch->changeSize(0, 0, QSizePolicy::Expanding);
m_labelRightStretch->changeSize(0, 0); m_labelRightStretch->changeSize(kDefaultTitleBarContentsMargin, 0, QSizePolicy::Fixed);
needsInvalidate = true; needsInvalidate = true;
} }
if (m_labelAlignment & Qt::AlignHCenter) { if (m_labelAlignment & Qt::AlignHCenter) {
@ -100,6 +101,8 @@ void StandardTitleBarPrivate::setTitleLabelAlignment(const Qt::Alignment value)
} }
Q_Q(StandardTitleBar); Q_Q(StandardTitleBar);
if (needsInvalidate) { if (needsInvalidate) {
// Tell the layout manager that we have changed the layout item's size
// manually to let it refresh the layout immediately.
q->layout()->invalidate(); q->layout()->invalidate();
} }
Q_EMIT q->titleLabelAlignmentChanged(); Q_EMIT q->titleLabelAlignmentChanged();
@ -162,6 +165,9 @@ void StandardTitleBarPrivate::updateTitleBarStyleSheet()
}(); }();
const QColor windowTitleLabelTextColor = (active ? ((dark || colorizedTitleBar) ? kDefaultWhiteColor : kDefaultBlackColor) : kDefaultDarkGrayColor); const QColor windowTitleLabelTextColor = (active ? ((dark || colorizedTitleBar) ? kDefaultWhiteColor : kDefaultBlackColor) : kDefaultDarkGrayColor);
m_windowTitleLabel->setStyleSheet(kStyleSheetColorTemplate.arg(windowTitleLabelTextColor.name())); m_windowTitleLabel->setStyleSheet(kStyleSheetColorTemplate.arg(windowTitleLabelTextColor.name()));
StandardSystemButtonPrivate::get(m_minimizeButton.data())->setInactive(!active);
StandardSystemButtonPrivate::get(m_maximizeButton.data())->setInactive(!active);
StandardSystemButtonPrivate::get(m_closeButton.data())->setInactive(!active);
Q_Q(StandardTitleBar); Q_Q(StandardTitleBar);
q->setStyleSheet(kStyleSheetBackgroundColorTemplate.arg(titleBarBackgroundColor.name())); q->setStyleSheet(kStyleSheetBackgroundColorTemplate.arg(titleBarBackgroundColor.name()));
q->update(); q->update();
@ -253,9 +259,8 @@ void StandardTitleBarPrivate::initialize()
systemButtonsOuterLayout->addLayout(systemButtonsInnerLayout); systemButtonsOuterLayout->addLayout(systemButtonsInnerLayout);
systemButtonsOuterLayout->addStretch(); systemButtonsOuterLayout->addStretch();
const auto titleBarLayout = new QHBoxLayout(q); const auto titleBarLayout = new QHBoxLayout(q);
titleBarLayout->setContentsMargins(0, 0, 0, 0);
titleBarLayout->setSpacing(0); titleBarLayout->setSpacing(0);
titleBarLayout->addSpacerItem(new QSpacerItem(kDefaultTitleBarContentsMargin, 0, QSizePolicy::Fixed, QSizePolicy::Fixed)); titleBarLayout->setContentsMargins(0, 0, 0, 0);
titleBarLayout->addLayout(titleLabelLayout); titleBarLayout->addLayout(titleLabelLayout);
titleBarLayout->addLayout(systemButtonsOuterLayout); titleBarLayout->addLayout(systemButtonsOuterLayout);
q->setLayout(titleBarLayout); q->setLayout(titleBarLayout);