Platform theme: fill QPalette::AccentColor with OS value

The AccentColor role, added in Qt 6.6, is currently populated with a
default value.

This patch implements populating the brush with OS values for Windows
and macOS.

Change-Id: Ic243c3b8664d50db3a2096a034de6ba672d9e2d2
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
This commit is contained in:
Yuhang Zhao 2023-05-25 11:48:54 +08:00 committed by Axel Spoerl
parent a33dd60e21
commit d6ed400037
2 changed files with 42 additions and 20 deletions

View File

@ -94,6 +94,9 @@ static QPalette *qt_mac_createSystemPalette()
palette->setColor(QPalette::Inactive, QPalette::PlaceholderText, qc);
palette->setColor(QPalette::Disabled, QPalette::PlaceholderText, qc);
qc = qt_mac_toQColor([NSColor controlAccentColor]);
palette->setColor(QPalette::AccentColor, qc);
return palette;
}

View File

@ -221,28 +221,48 @@ static QColor placeHolderColor(QColor textColor)
return textColor;
}
[[maybe_unused]] [[nodiscard]] static inline QColor qt_accentColor()
{
const QWinRegistryKey registry(HKEY_CURRENT_USER, LR"(Software\Microsoft\Windows\DWM)");
if (!registry.isValid())
return {};
const QVariant value = registry.value(L"AccentColor");
if (!value.isValid())
return {};
// The retrieved value is in the #AABBGGRR format, we need to
// convert it to the #AARRGGBB format which Qt expects.
const QColor abgr = QColor::fromRgba(qvariant_cast<DWORD>(value));
if (!abgr.isValid())
return {};
return QColor::fromRgb(abgr.blue(), abgr.green(), abgr.red(), abgr.alpha());
}
/*
This is used when the theme is light mode, and when the theme is dark but the
application doesn't support dark mode. In the latter case, we need to check.
*/
void QWindowsTheme::populateLightSystemBasePalette(QPalette &result)
{
QColor background = getSysColor(COLOR_BTNFACE);
QColor textColor = getSysColor(COLOR_WINDOWTEXT);
QColor accent = getSysColor(COLOR_HIGHLIGHT);
const QColor background = getSysColor(COLOR_BTNFACE);
const QColor textColor = getSysColor(COLOR_WINDOWTEXT);
#if QT_CONFIG(cpp_winrt)
// respect the Windows 11 accent color
using namespace winrt::Windows::UI::ViewManagement;
const auto settings = UISettings();
accent = getSysColor(settings.GetColorValue(UIColorType::Accent));
const QColor accent = getSysColor(settings.GetColorValue(UIColorType::Accent));
const QColor accentDarkest = getSysColor(settings.GetColorValue(UIColorType::AccentDark3));
#else
const QColor accent = qt_accentColor();
const QColor accentDarkest = accent.darker(120 * 120 * 120);
#endif
const QColor linkColor = accent;
const QColor btnFace = background;
const QColor btnHighlight = getSysColor(COLOR_BTNHIGHLIGHT);
result.setColor(QPalette::Highlight, accent);
result.setColor(QPalette::Highlight, getSysColor(COLOR_HIGHLIGHT));
result.setColor(QPalette::WindowText, getSysColor(COLOR_WINDOWTEXT));
result.setColor(QPalette::Button, btnFace);
result.setColor(QPalette::Light, btnHighlight);
@ -257,9 +277,10 @@ void QWindowsTheme::populateLightSystemBasePalette(QPalette &result)
result.setColor(QPalette::Midlight, getSysColor(COLOR_3DLIGHT));
result.setColor(QPalette::Shadow, getSysColor(COLOR_3DDKSHADOW));
result.setColor(QPalette::HighlightedText, getSysColor(COLOR_HIGHLIGHTTEXT));
result.setColor(QPalette::AccentColor, accent);
result.setColor(QPalette::Link, Qt::blue);
result.setColor(QPalette::LinkVisited, Qt::magenta);
result.setColor(QPalette::Link, linkColor);
result.setColor(QPalette::LinkVisited, accentDarkest);
result.setColor(QPalette::Inactive, QPalette::Button, result.button().color());
result.setColor(QPalette::Inactive, QPalette::Window, result.window().color());
result.setColor(QPalette::Inactive, QPalette::Light, result.light().color());
@ -293,19 +314,18 @@ static void populateDarkSystemBasePalette(QPalette &result)
const QColor accentLight = getSysColor(settings.GetColorValue(UIColorType::AccentLight1));
const QColor accentLighter = getSysColor(settings.GetColorValue(UIColorType::AccentLight2));
const QColor accentLightest = getSysColor(settings.GetColorValue(UIColorType::AccentLight3));
const QColor linkColor = accent;
#else
const QColor foreground = Qt::white;
const QColor background = QColor(0x1E, 0x1E, 0x1E);
const QColor accent = QColor(0x00, 0x55, 0xff);
const QColor accent = qt_accentColor();
const QColor accentDark = accent.darker(120);
const QColor accentDarker = accentDark.darker(120);
const QColor accentDarkest = accentDarker.darker(120);
const QColor accentLight = accent.lighter(120);
const QColor accentLighter = accentLight.lighter(120);
const QColor accentLightest = accentLighter.lighter(120);
const QColor linkColor = Qt::blue;
#endif
const QColor linkColor = accent;
const QColor buttonColor = background.lighter(200);
result.setColor(QPalette::All, QPalette::WindowText, foreground);
@ -331,6 +351,7 @@ static void populateDarkSystemBasePalette(QPalette &result)
result.setColor(QPalette::All, QPalette::ToolTipBase, buttonColor);
result.setColor(QPalette::All, QPalette::ToolTipText, foreground.darker(120));
result.setColor(QPalette::All, QPalette::PlaceholderText, placeHolderColor(foreground));
result.setColor(QPalette::All, QPalette::AccentColor, accent);
}
static QPalette systemPalette(bool light)
@ -346,6 +367,8 @@ static QPalette systemPalette(bool light)
result.color(QPalette::Inactive, QPalette::Window));
result.setColor(QPalette::Inactive, QPalette::HighlightedText,
result.color(QPalette::Inactive, QPalette::Text));
result.setColor(QPalette::Inactive, QPalette::AccentColor,
result.color(QPalette::Inactive, QPalette::Window));
}
const QColor disabled = mixColors(result.windowText().color(), result.button().color());
@ -359,6 +382,7 @@ static QPalette systemPalette(bool light)
result.setColor(QPalette::Disabled, QPalette::ButtonText, disabled);
result.setColor(QPalette::Disabled, QPalette::Highlight, result.color(QPalette::Highlight));
result.setColor(QPalette::Disabled, QPalette::HighlightedText, result.color(QPalette::HighlightedText));
result.setColor(QPalette::Disabled, QPalette::AccentColor, disabled);
result.setColor(QPalette::Disabled, QPalette::Base, result.window().color());
return result;
}
@ -549,7 +573,6 @@ void QWindowsTheme::clearPalettes()
void QWindowsTheme::refreshPalettes()
{
if (!QGuiApplication::desktopSettingsAware())
return;
const bool light =
@ -567,19 +590,15 @@ void QWindowsTheme::refreshPalettes()
const QColor accent = getSysColor(settings.GetColorValue(UIColorType::Accent));
const QColor accentLight = getSysColor(settings.GetColorValue(UIColorType::AccentLight1));
const QColor accentDarkest = getSysColor(settings.GetColorValue(UIColorType::AccentDark3));
#else
const QColor accent = qt_accentColor();
const QColor accentLight = accent.lighter(120);
const QColor accentDarkest = accent.darker(120 * 120 * 120);
#endif
m_palettes[CheckBoxPalette] = new QPalette(*m_palettes[SystemPalette]);
m_palettes[CheckBoxPalette]->setColor(QPalette::Active, QPalette::Base, accent);
m_palettes[CheckBoxPalette]->setColor(QPalette::Active, QPalette::Button, accentLight);
m_palettes[CheckBoxPalette]->setColor(QPalette::Inactive, QPalette::Base, accentDarkest);
#else
m_palettes[ButtonPalette] = new QPalette(*m_palettes[SystemPalette]);
m_palettes[ButtonPalette]->setColor(QPalette::Button, QColor(0x666666u));
const QColor checkBoxBlue(0x0078d7u);
m_palettes[CheckBoxPalette] = new QPalette(*m_palettes[SystemPalette]);
m_palettes[CheckBoxPalette]->setColor(QPalette::Base, checkBoxBlue);
m_palettes[CheckBoxPalette]->setColor(QPalette::Button, checkBoxBlue);
m_palettes[CheckBoxPalette]->setColor(QPalette::ButtonText, Qt::white);
#endif
m_palettes[RadioButtonPalette] = new QPalette(*m_palettes[CheckBoxPalette]);
}
}