summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMohammadHossein Qanbari <[email protected]>2025-04-08 15:26:53 +0200
committerMohammadHossein Qanbari <[email protected]>2025-05-29 16:34:06 +0200
commit6a21e0e212732fb2b919f5dd18b1c48ef7285162 (patch)
tree9b61c9fd59d18262576903542167c80dedd50e71
parent393c294e102bcd733141539552fda2f148e8b51b (diff)
QGnomeTheme: Enhance system color scheme detection
Previously, QGnomeTheme relied on the theme name to determine the system's color scheme when a "SettingChanged" signal was emitted via dbus. However, this approach overlooked the "color-scheme" property in the signal, which directly provides the updated light/dark mode information. This patch updates QGnomeTheme to use the "color-scheme" property from the dbus signal, ensuring accurate detection of changes in the system's color scheme. The theme name fallback is retained for scenarios where "color-scheme" data is not provided. See also the XDG Desktop Portal documentation: https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.Settings.html Related to this commit: 4ac89dad78772ce90649b9846efa17319deba28f Task-number: QTBUG-133595 Change-Id: I2c3982fd9871d76184f1b4233d95e7a5e0a34ad1 Reviewed-by: Oliver Eftevaag <[email protected]>
-rw-r--r--src/gui/platform/unix/qgnometheme.cpp92
-rw-r--r--src/gui/platform/unix/qgnometheme_p.h8
2 files changed, 72 insertions, 28 deletions
diff --git a/src/gui/platform/unix/qgnometheme.cpp b/src/gui/platform/unix/qgnometheme.cpp
index aafaff3732b..0f34003c0ef 100644
--- a/src/gui/platform/unix/qgnometheme.cpp
+++ b/src/gui/platform/unix/qgnometheme.cpp
@@ -20,7 +20,43 @@ QT_BEGIN_NAMESPACE
#if QT_CONFIG(dbus)
Q_STATIC_LOGGING_CATEGORY(lcQpaThemeGnome, "qt.qpa.theme.gnome")
-#endif
+
+namespace {
+// https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.Settings.html
+enum class XDG_ColorScheme : uint { NoPreference, PreferDark, PreferLight };
+
+constexpr Qt::ColorScheme convertColorScheme(XDG_ColorScheme colorScheme)
+{
+ switch (colorScheme) {
+ case XDG_ColorScheme::NoPreference:
+ return Qt::ColorScheme::Unknown;
+ case XDG_ColorScheme::PreferDark:
+ return Qt::ColorScheme::Dark;
+ case XDG_ColorScheme::PreferLight:
+ return Qt::ColorScheme::Light;
+ default:
+ Q_UNREACHABLE_RETURN(Qt::ColorScheme::Unknown);
+ break;
+ }
+}
+
+constexpr XDG_ColorScheme convertColorScheme(Qt::ColorScheme colorScheme)
+{
+ switch (colorScheme) {
+ case Qt::ColorScheme::Unknown:
+ return XDG_ColorScheme::NoPreference;
+ case Qt::ColorScheme::Light:
+ return XDG_ColorScheme::PreferLight;
+ case Qt::ColorScheme::Dark:
+ return XDG_ColorScheme::PreferDark;
+ default:
+ Q_UNREACHABLE_RETURN(XDG_ColorScheme::NoPreference);
+ break;
+ }
+}
+} // namespace
+
+#endif // QT_CONFIG(dbus)
/*!
\class QGnomeTheme
@@ -49,19 +85,8 @@ QGnomeThemePrivate::QGnomeThemePrivate()
message << appearanceNamespace << colorSchemeKey;
QDBusReply<QVariant> reply = dbus.call(message);
if (Q_LIKELY(reply.isValid())) {
- uint xdgColorSchemeValue = reply.value().toUInt();
- switch (xdgColorSchemeValue) {
- case 1:
- m_colorScheme = Qt::ColorScheme::Dark;
- QWindowSystemInterface::handleThemeChange();
- break;
- case 2:
- m_colorScheme = Qt::ColorScheme::Light;
- QWindowSystemInterface::handleThemeChange();
- break;
- default:
- break;
- }
+ m_colorScheme = convertColorScheme(XDG_ColorScheme{ reply.value().toUInt() });
+ QWindowSystemInterface::handleThemeChange();
}
message.setArguments({});
@@ -117,8 +142,11 @@ bool QGnomeThemePrivate::initDbus()
}
switch (setting) {
+ case QDBusListener::Setting::ColorScheme:
+ updateColorScheme(convertColorScheme(XDG_ColorScheme{ value.toUInt() }));
+ break;
case QDBusListener::Setting::Theme:
- updateColorScheme(value.toString());
+ m_themeName = value.toString();
break;
case QDBusListener::Setting::Contrast:
updateHighContrast(static_cast<Qt::ContrastPreference>(value.toUInt()));
@@ -131,19 +159,29 @@ bool QGnomeThemePrivate::initDbus()
return QObject::connect(dbus.get(), &QDBusListener::settingChanged, dbus.get(), wrapper);
}
-void QGnomeThemePrivate::updateColorScheme(const QString &themeName)
+Qt::ColorScheme QGnomeThemePrivate::colorScheme() const
{
- const auto oldColorScheme = m_colorScheme;
- if (themeName.contains(QLatin1StringView("light"), Qt::CaseInsensitive)) {
- m_colorScheme = Qt::ColorScheme::Light;
- } else if (themeName.contains(QLatin1StringView("dark"), Qt::CaseInsensitive)) {
- m_colorScheme = Qt::ColorScheme::Dark;
- } else {
- m_colorScheme = Qt::ColorScheme::Unknown;
- }
+ if (m_colorScheme != Qt::ColorScheme::Unknown)
+ return m_colorScheme;
+
+ // If the color scheme is set to Unknown by mistake or is not set at all,
+ // then maybe the theme name contains a hint about the color scheme.
+ // Let's hope the theme name does not include any accent color name
+ // which contains "dark" or "light" in it (e.g. lightblue). At the moment they don't.
+ if (m_themeName.contains(QLatin1StringView("light"), Qt::CaseInsensitive))
+ return Qt::ColorScheme::Light;
+ else if (m_themeName.contains(QLatin1StringView("dark"), Qt::CaseInsensitive))
+ return Qt::ColorScheme::Dark;
+ else
+ return Qt::ColorScheme::Unknown;
+}
- if (oldColorScheme != m_colorScheme)
- QWindowSystemInterface::handleThemeChange();
+void QGnomeThemePrivate::updateColorScheme(Qt::ColorScheme colorScheme)
+{
+ if (m_colorScheme == colorScheme)
+ return;
+ m_colorScheme = colorScheme;
+ QWindowSystemInterface::handleThemeChange();
}
void QGnomeThemePrivate::updateHighContrast(Qt::ContrastPreference contrast)
@@ -245,7 +283,7 @@ QPlatformMenuBar *QGnomeTheme::createPlatformMenuBar() const
Qt::ColorScheme QGnomeTheme::colorScheme() const
{
- return d_func()->m_colorScheme;
+ return d_func()->colorScheme();
}
Qt::ContrastPreference QGnomeTheme::contrastPreference() const
diff --git a/src/gui/platform/unix/qgnometheme_p.h b/src/gui/platform/unix/qgnometheme_p.h
index 41df765eccf..9c59646c715 100644
--- a/src/gui/platform/unix/qgnometheme_p.h
+++ b/src/gui/platform/unix/qgnometheme_p.h
@@ -68,8 +68,14 @@ public:
private:
std::unique_ptr<QDBusListener> dbus;
std::unique_ptr<QDBusPendingCallWatcher> pendingCallWatcher;
+ QString m_themeName;
+
+public:
+ Qt::ColorScheme colorScheme() const;
+
+private:
bool initDbus();
- void updateColorScheme(const QString &themeName);
+ void updateColorScheme(Qt::ColorScheme colorScheme);
void updateHighContrast(Qt::ContrastPreference contrast);
#endif // QT_CONFIG(dbus)
};