Detect appearance by colors unless GTK theme name contains "dark"

QGtk3Theme detects the appearance property by theme name: If the name
contains the keyword "dark", the theme is considered to be dark and
otherwise light.

This detection logic fails, when the GTK theme is dark without
containing the "dark" keyword, e.g. the dark theme "Adapta-Nokto".
While QGtk3Theme imports the right colors in that case, it wrongly
identifies a light theme.

This patch adapts the detection logic: If the theme name contains the
"dark" keyword, it is considered a dark theme without further checks.
If it doesn't, the current GTK3 theme's default background and
foreground colors will be read. If the foreground is lighter than the
background, the theme is considered dark. If the background is lighter
than the foreground, the theme is considered light. If both colors are
identical, the appearance will be Qt::Appearance::Unknown.

Task-number: QTBUG-93955
Pick-to: 6.5
Change-Id: I0e0f4870a1397b6a7918331a852284bb1c91199e
Reviewed-by: Oliver Eftevaag <oliver.eftevaag@qt.io>
This commit is contained in:
Axel Spoerl 2022-12-19 08:45:59 +01:00
parent 988c7bfcae
commit 7b64eb71c0
3 changed files with 20 additions and 1 deletions

View File

@ -400,6 +400,22 @@ const QString QGtk3Interface::themeName() const
return QLatin1StringView(theme_name);
}
Qt::Appearance QGtk3Interface::appearanceByColors() const
{
const QColor background = color(widget(QGtkWidget::gtk_Default),
QGtkColorSource::Background,
GTK_STATE_FLAG_ACTIVE);
const QColor foreground = color(widget(QGtkWidget::gtk_Default),
QGtkColorSource::Foreground,
GTK_STATE_FLAG_ACTIVE);
if (foreground.lightness() > background.lightness())
return Qt::Appearance::Dark;
if (foreground.lightness() < background.lightness())
return Qt::Appearance::Light;
return Qt::Appearance::Unknown;
}
inline constexpr QGtk3Interface::QGtkWidget QGtk3Interface::toWidgetType(QPlatformTheme::Font type)
{
switch (type) {

View File

@ -99,6 +99,9 @@ public:
// Return current GTK theme name
const QString themeName() const;
// Derive appearance from default colors
Qt::Appearance appearanceByColors() const;
// Convert GTK state to/from string
static int toGtkState(const QString &state);
static const QLatin1String fromGtkState(GtkStateFlags state);

View File

@ -222,7 +222,7 @@ void QGtk3Storage::populateMap()
// Derive appearance from theme name
m_appearance = newThemeName.contains("dark"_L1, Qt::CaseInsensitive)
? Qt::Appearance::Dark : Qt::Appearance::Light;
? Qt::Appearance::Dark : m_interface->appearanceByColors();
if (m_themeName.isEmpty()) {
qCDebug(lcQGtk3Interface) << "GTK theme initialized:" << newThemeName << m_appearance;