summaryrefslogtreecommitdiffstats
path: root/src/gui/platform/unix/qgenericunixthemes.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/platform/unix/qgenericunixthemes.cpp')
-rw-r--r--src/gui/platform/unix/qgenericunixthemes.cpp648
1 files changed, 515 insertions, 133 deletions
diff --git a/src/gui/platform/unix/qgenericunixthemes.cpp b/src/gui/platform/unix/qgenericunixthemes.cpp
index ad229af624..90971ba94c 100644
--- a/src/gui/platform/unix/qgenericunixthemes.cpp
+++ b/src/gui/platform/unix/qgenericunixthemes.cpp
@@ -33,6 +33,12 @@
#include <QDBusConnectionInterface>
#include <private/qdbusplatformmenu_p.h>
#include <private/qdbusmenubar_p.h>
+#include <private/qflatmap_p.h>
+#include <QJsonDocument>
+#include <QJsonArray>
+#include <QJsonObject>
+#include <QJsonValue>
+#include <QJsonParseError>
#endif
#if !defined(QT_NO_DBUS) && !defined(QT_NO_SYSTEMTRAYICON)
#include <private/qdbustrayicon_p.h>
@@ -72,17 +78,14 @@ static const char defaultFixedFontNameC[] = "monospace";
enum { defaultSystemFontSize = 9 };
#if !defined(QT_NO_DBUS) && !defined(QT_NO_SYSTEMTRAYICON)
-static bool isDBusTrayAvailable() {
- static bool dbusTrayAvailable = false;
- static bool dbusTrayAvailableKnown = false;
- if (!dbusTrayAvailableKnown) {
- QDBusMenuConnection conn;
- if (conn.isStatusNotifierHostRegistered())
- dbusTrayAvailable = true;
- dbusTrayAvailableKnown = true;
- qCDebug(qLcTray) << "D-Bus tray available:" << dbusTrayAvailable;
- }
- return dbusTrayAvailable;
+static bool shouldUseDBusTray() {
+ // There's no other tray implementation to fallback to on non-X11
+ // and QDBusTrayIcon can register the icon on the fly after creation
+ if (QGuiApplication::platformName() != "xcb"_L1)
+ return true;
+ const bool result = QDBusMenuConnection().isWatcherRegistered();
+ qCDebug(qLcTray) << "D-Bus tray available:" << result;
+ return result;
}
#endif
@@ -119,7 +122,7 @@ static bool isDBusGlobalMenuAvailable()
/*!
* \internal
* The QGenericUnixThemeDBusListener class listens to the SettingChanged DBus signal
- * and translates it into the QDbusSettingType enum.
+ * and translates it into combinations of the enums \c Provider and \c Setting.
* Upon construction, it logs success/failure of the DBus connection.
*
* The signal settingChanged delivers the normalized setting type and the new value as a string.
@@ -131,35 +134,98 @@ class QGenericUnixThemeDBusListener : public QObject
Q_OBJECT
public:
- QGenericUnixThemeDBusListener(const QString &service, const QString &path, const QString &interface, const QString &signal);
- enum class SettingType {
- KdeGlobalTheme,
- KdeApplicationStyle,
- GtkTheme,
- Unknown
+ enum class Provider {
+ Kde,
+ Gtk,
+ Gnome,
};
- Q_ENUM(SettingType)
+ Q_ENUM(Provider)
- static SettingType toSettingType(const QString &location, const QString &key);
+ enum class Setting {
+ Theme,
+ ApplicationStyle,
+ ColorScheme,
+ };
+ Q_ENUM(Setting)
+
+ QGenericUnixThemeDBusListener();
+ QGenericUnixThemeDBusListener(const QString &service, const QString &path,
+ const QString &interface, const QString &signal);
private Q_SLOTS:
void onSettingChanged(const QString &location, const QString &key, const QDBusVariant &value);
Q_SIGNALS:
- void settingChanged(QGenericUnixThemeDBusListener::SettingType type, const QString &value);
+ void settingChanged(QGenericUnixThemeDBusListener::Provider provider,
+ QGenericUnixThemeDBusListener::Setting setting,
+ const QString &value);
+
+private:
+ struct DBusKey
+ {
+ QString location;
+ QString key;
+ DBusKey(const QString &loc, const QString &k) : location(loc), key(k) {};
+ bool operator<(const DBusKey &other) const
+ {
+ return location + key < other.location + other.key;
+ }
+ };
+
+ struct ChangeSignal
+ {
+ Provider provider;
+ Setting setting;
+ ChangeSignal(Provider p, Setting s) : provider(p), setting(s) {}
+ ChangeSignal() {}
+ };
+
+ // Json keys
+ static constexpr QLatin1StringView s_dbusLocation = QLatin1StringView("DBusLocation");
+ static constexpr QLatin1StringView s_dbusKey = QLatin1StringView("DBusKey");
+ static constexpr QLatin1StringView s_provider = QLatin1StringView("Provider");
+ static constexpr QLatin1StringView s_setting = QLatin1StringView("Setting");
+ static constexpr QLatin1StringView s_signals = QLatin1StringView("DbusSignals");
+ static constexpr QLatin1StringView s_root = QLatin1StringView("Qt.qpa.DBusSignals");
+ QFlatMap <DBusKey, ChangeSignal> m_signalMap;
+
+ void init(const QString &service, const QString &path,
+ const QString &interface, const QString &signal);
+
+ std::optional<ChangeSignal> findSignal(const QString &location, const QString &key) const;
+ void populateSignalMap();
+ void loadJson(const QString &fileName);
+ void saveJson(const QString &fileName) const;
};
QGenericUnixThemeDBusListener::QGenericUnixThemeDBusListener(const QString &service,
const QString &path, const QString &interface, const QString &signal)
{
+ init (service, path, interface, signal);
+}
+
+QGenericUnixThemeDBusListener::QGenericUnixThemeDBusListener()
+{
+ static constexpr QLatin1StringView service("");
+ static constexpr QLatin1StringView path("/org/freedesktop/portal/desktop");
+ static constexpr QLatin1StringView interface("org.freedesktop.portal.Settings");
+ static constexpr QLatin1StringView signal("SettingChanged");
+
+ init (service, path, interface, signal);
+}
+
+void QGenericUnixThemeDBusListener::init(const QString &service, const QString &path,
+ const QString &interface, const QString &signal)
+{
QDBusConnection dbus = QDBusConnection::sessionBus();
const bool dBusRunning = dbus.isConnected();
bool dBusSignalConnected = false;
#define LOG service << path << interface << signal;
if (dBusRunning) {
+ populateSignalMap();
qRegisterMetaType<QDBusVariant>();
dBusSignalConnected = dbus.connect(service, path, interface, signal, this,
SLOT(onSettingChanged(QString,QString,QDBusVariant)));
@@ -182,26 +248,155 @@ QGenericUnixThemeDBusListener::QGenericUnixThemeDBusListener(const QString &serv
#undef LOG
}
-QGenericUnixThemeDBusListener::SettingType QGenericUnixThemeDBusListener::toSettingType(
- const QString &location, const QString &key)
-{
- if (location == QLatin1StringView("org.kde.kdeglobals.KDE")
- && key == QLatin1StringView("widgetStyle"))
- return SettingType::KdeApplicationStyle;
- if (location == QLatin1StringView("org.kde.kdeglobals.General")
- && key == QLatin1StringView("ColorScheme"))
- return SettingType::KdeGlobalTheme;
- if (location == QLatin1StringView("org.gnome.desktop.interface")
- && key == QLatin1StringView("gtk-theme"))
- return SettingType::GtkTheme;
- return SettingType::Unknown;
+void QGenericUnixThemeDBusListener::loadJson(const QString &fileName)
+{
+ Q_ASSERT(!fileName.isEmpty());
+#define CHECK(cond, warning)\
+ if (!cond) {\
+ qCWarning(lcQpaThemeDBus) << fileName << warning << "Falling back to default.";\
+ return;\
+ }
+
+#define PARSE(var, enumeration, string)\
+ enumeration var;\
+ {\
+ bool success;\
+ const int val = QMetaEnum::fromType<enumeration>().keyToValue(string.toLatin1(), &success);\
+ CHECK(success, "Parse Error: Invalid value" << string << "for" << #var);\
+ var = static_cast<enumeration>(val);\
+ }
+
+ QFile file(fileName);
+ CHECK(file.exists(), fileName << "doesn't exist.");
+ CHECK(file.open(QIODevice::ReadOnly), "could not be opened for reading.");
+
+ QJsonParseError error;
+ QJsonDocument doc = QJsonDocument::fromJson(file.readAll(), &error);
+ CHECK((error.error == QJsonParseError::NoError), error.errorString());
+ CHECK(doc.isObject(), "Parse Error: Expected root object" << s_root);
+
+ const QJsonObject &root = doc.object();
+ CHECK(root.contains(s_root), "Parse Error: Expected root object" << s_root);
+ CHECK(root[s_root][s_signals].isArray(), "Parse Error: Expected array" << s_signals);
+
+ const QJsonArray &sigs = root[s_root][s_signals].toArray();
+ CHECK((sigs.count() > 0), "Parse Error: Found empty array" << s_signals);
+
+ for (auto sig = sigs.constBegin(); sig != sigs.constEnd(); ++sig) {
+ CHECK(sig->isObject(), "Parse Error: Expected object array" << s_signals);
+ const QJsonObject &obj = sig->toObject();
+ CHECK(obj.contains(s_dbusLocation), "Parse Error: Expected key" << s_dbusLocation);
+ CHECK(obj.contains(s_dbusKey), "Parse Error: Expected key" << s_dbusKey);
+ CHECK(obj.contains(s_provider), "Parse Error: Expected key" << s_provider);
+ CHECK(obj.contains(s_setting), "Parse Error: Expected key" << s_setting);
+ const QString &location = obj[s_dbusLocation].toString();
+ const QString &key = obj[s_dbusKey].toString();
+ const QString &providerString = obj[s_provider].toString();
+ const QString &settingString = obj[s_setting].toString();
+ PARSE(provider, Provider, providerString);
+ PARSE(setting, Setting, settingString);
+ const DBusKey dkey(location, key);
+ CHECK (!m_signalMap.contains(dkey), "Duplicate key" << location << key);
+ m_signalMap.insert(dkey, ChangeSignal(provider, setting));
+ }
+#undef PARSE
+#undef CHECK
+
+ if (m_signalMap.count() > 0)
+ qCInfo(lcQpaThemeDBus) << "Successfully imported" << fileName;
+ else
+ qCWarning(lcQpaThemeDBus) << "No data imported from" << fileName << "falling back to default.";
+
+#ifdef QT_DEBUG
+ const int count = m_signalMap.count();
+ if (count == 0)
+ return;
+
+ qCDebug(lcQpaThemeDBus) << "Listening to" << count << "signals:";
+ for (auto it = m_signalMap.constBegin(); it != m_signalMap.constEnd(); ++it) {
+ qDebug() << it.key().key << it.key().location << "mapped to"
+ << it.value().provider << it.value().setting;
+ }
+
+#endif
+}
+
+void QGenericUnixThemeDBusListener::saveJson(const QString &fileName) const
+{
+ Q_ASSERT(!m_signalMap.isEmpty());
+ Q_ASSERT(!fileName.isEmpty());
+ QFile file(fileName);
+ if (!file.open(QIODevice::WriteOnly)) {
+ qCWarning(lcQpaThemeDBus) << fileName << "could not be opened for writing.";
+ return;
+ }
+
+ QJsonArray sigs;
+ for (auto sig = m_signalMap.constBegin(); sig != m_signalMap.constEnd(); ++sig) {
+ const DBusKey &dkey = sig.key();
+ const ChangeSignal &csig = sig.value();
+ QJsonObject obj;
+ obj[s_dbusLocation] = dkey.location;
+ obj[s_dbusKey] = dkey.key;
+ obj[s_provider] = QLatin1StringView(QMetaEnum::fromType<Provider>()
+ .valueToKey(static_cast<int>(csig.provider)));
+ obj[s_setting] = QLatin1StringView(QMetaEnum::fromType<Setting>()
+ .valueToKey(static_cast<int>(csig.setting)));
+ sigs.append(obj);
+ }
+ QJsonObject obj;
+ obj[s_signals] = sigs;
+ QJsonObject root;
+ root[s_root] = obj;
+ QJsonDocument doc(root);
+ file.write(doc.toJson());
+ file.close();
+}
+
+void QGenericUnixThemeDBusListener::populateSignalMap()
+{
+ m_signalMap.clear();
+ const QString &loadJsonFile = qEnvironmentVariable("QT_QPA_DBUS_SIGNALS");
+ if (!loadJsonFile.isEmpty())
+ loadJson(loadJsonFile);
+ if (!m_signalMap.isEmpty())
+ return;
+
+ m_signalMap.insert(DBusKey("org.kde.kdeglobals.KDE"_L1, "widgetStyle"_L1),
+ ChangeSignal(Provider::Kde, Setting::ApplicationStyle));
+
+ m_signalMap.insert(DBusKey("org.kde.kdeglobals.General"_L1, "ColorScheme"_L1),
+ ChangeSignal(Provider::Kde, Setting::Theme));
+
+ m_signalMap.insert(DBusKey("org.gnome.desktop.interface"_L1, "gtk-theme"_L1),
+ ChangeSignal(Provider::Gtk, Setting::Theme));
+
+ m_signalMap.insert(DBusKey("org.freedesktop.appearance"_L1, "color-scheme"_L1),
+ ChangeSignal(Provider::Gnome, Setting::ColorScheme));
+
+ const QString &saveJsonFile = qEnvironmentVariable("QT_QPA_DBUS_SIGNALS_SAVE");
+ if (!saveJsonFile.isEmpty())
+ saveJson(saveJsonFile);
+}
+
+std::optional<QGenericUnixThemeDBusListener::ChangeSignal>
+ QGenericUnixThemeDBusListener::findSignal(const QString &location, const QString &key) const
+{
+ const DBusKey dkey(location, key);
+ std::optional<QGenericUnixThemeDBusListener::ChangeSignal> ret;
+ if (m_signalMap.contains(dkey))
+ ret.emplace(m_signalMap.value(dkey));
+
+ return ret;
}
void QGenericUnixThemeDBusListener::onSettingChanged(const QString &location, const QString &key, const QDBusVariant &value)
{
- const SettingType type = toSettingType(location, key);
- if (type != SettingType::Unknown)
- emit settingChanged(type, value.variant().toString());
+ auto sig = findSignal(location, key);
+ if (!sig.has_value())
+ return;
+
+ emit settingChanged(sig.value().provider, sig.value().setting, value.variant().toString());
}
#endif //QT_NO_DBUS
@@ -278,7 +473,7 @@ QPlatformMenuBar *QGenericUnixTheme::createPlatformMenuBar() const
#if !defined(QT_NO_DBUS) && !defined(QT_NO_SYSTEMTRAYICON)
QPlatformSystemTrayIcon *QGenericUnixTheme::createPlatformSystemTrayIcon() const
{
- if (isDBusTrayAvailable())
+ if (shouldUseDBusTray())
return new QDBusTrayIcon();
return nullptr;
}
@@ -308,6 +503,8 @@ QVariant QGenericUnixTheme::themeHint(ThemeHint hint) const
return QVariant(mouseCursorTheme());
case QPlatformTheme::MouseCursorSize:
return QVariant(mouseCursorSize());
+ case QPlatformTheme::PreferFileIconFromTheme:
+ return true;
default:
break;
}
@@ -343,6 +540,48 @@ class QKdeThemePrivate : public QPlatformThemePrivate
{
public:
+ enum class KdeSettingType {
+ Root,
+ KDE,
+ Icons,
+ ToolBarIcons,
+ ToolBarStyle,
+ Fonts,
+ Colors,
+ };
+
+ enum class KdeSetting {
+ WidgetStyle,
+ ColorScheme,
+ SingleClick,
+ ShowIconsOnPushButtons,
+ IconTheme,
+ ToolBarIconSize,
+ ToolButtonStyle,
+ WheelScrollLines,
+ DoubleClickInterval,
+ StartDragDistance,
+ StartDragTime,
+ CursorBlinkRate,
+ Font,
+ Fixed,
+ MenuFont,
+ ToolBarFont,
+ ButtonBackground,
+ WindowBackground,
+ ViewForeground,
+ WindowForeground,
+ ViewBackground,
+ SelectionBackground,
+ SelectionForeground,
+ ViewBackgroundAlternate,
+ ButtonForeground,
+ ViewForegroundLink,
+ ViewForegroundVisited,
+ TooltipBackground,
+ TooltipForeground,
+ };
+
QKdeThemePrivate(const QStringList &kdeDirs, int kdeVersion);
static QString kdeGlobals(const QString &kdeDir, int kdeVersion)
@@ -353,7 +592,9 @@ public:
}
void refresh();
- static QVariant readKdeSetting(const QString &key, const QStringList &kdeDirs, int kdeVersion, QHash<QString, QSettings*> &kdeSettings);
+ static QVariant readKdeSetting(KdeSetting s, const QStringList &kdeDirs, int kdeVersion, QHash<QString, QSettings*> &settings);
+ QVariant readKdeSetting(KdeSetting s) const;
+ void clearKdeSettings() const;
static void readKdeSystemPalette(const QStringList &kdeDirs, int kdeVersion, QHash<QString, QSettings*> &kdeSettings, QPalette *pal);
static QFont *kdeFont(const QVariant &fontValue);
static QStringList kdeIconThemeSearchPaths(const QStringList &kdeDirs);
@@ -374,31 +615,38 @@ public:
int startDragDist = 10;
int startDragTime = 500;
int cursorBlinkRate = 1000;
- Qt::Appearance m_appearance = Qt::Appearance::Unknown;
- void updateAppearance(const QString &themeName);
+ Qt::ColorScheme m_colorScheme = Qt::ColorScheme::Unknown;
+ void updateColorScheme(const QString &themeName);
-#ifndef QT_NO_DBUS
private:
+ mutable QHash<QString, QSettings *> kdeSettings;
+#ifndef QT_NO_DBUS
std::unique_ptr<QGenericUnixThemeDBusListener> dbus;
bool initDbus();
- void settingChangedHandler(QGenericUnixThemeDBusListener::SettingType type, const QString &value);
+ void settingChangedHandler(QGenericUnixThemeDBusListener::Provider provider,
+ QGenericUnixThemeDBusListener::Setting setting,
+ const QString &value);
#endif // QT_NO_DBUS
};
#ifndef QT_NO_DBUS
-void QKdeThemePrivate::settingChangedHandler(QGenericUnixThemeDBusListener::SettingType type, const QString &value)
+void QKdeThemePrivate::settingChangedHandler(QGenericUnixThemeDBusListener::Provider provider,
+ QGenericUnixThemeDBusListener::Setting setting,
+ const QString &value)
{
- switch (type) {
- case QGenericUnixThemeDBusListener::SettingType::KdeGlobalTheme:
+ if (provider != QGenericUnixThemeDBusListener::Provider::Kde)
+ return;
+
+ switch (setting) {
+ case QGenericUnixThemeDBusListener::Setting::ColorScheme:
+ qCDebug(lcQpaThemeDBus) << "KDE color theme changed to:" << value;
+ break;
+ case QGenericUnixThemeDBusListener::Setting::Theme:
qCDebug(lcQpaThemeDBus) << "KDE global theme changed to:" << value;
break;
- case QGenericUnixThemeDBusListener::SettingType::KdeApplicationStyle:
+ case QGenericUnixThemeDBusListener::Setting::ApplicationStyle:
qCDebug(lcQpaThemeDBus) << "KDE application style changed to:" << value;
break;
- case QGenericUnixThemeDBusListener::SettingType::GtkTheme:
- return; // KDE can change GTK2 / GTK3 themes. Ignored here, handled in GnomeTheme
- case QGenericUnixThemeDBusListener::SettingType::Unknown:
- Q_UNREACHABLE();
}
refresh();
@@ -406,20 +654,17 @@ void QKdeThemePrivate::settingChangedHandler(QGenericUnixThemeDBusListener::Sett
bool QKdeThemePrivate::initDbus()
{
- static constexpr QLatin1StringView service("");
- static constexpr QLatin1StringView path("/org/freedesktop/portal/desktop");
- static constexpr QLatin1StringView interface("org.freedesktop.portal.Settings");
- static constexpr QLatin1StringView signal("SettingChanged");
-
- dbus.reset(new QGenericUnixThemeDBusListener(service, path, interface, signal));
+ dbus.reset(new QGenericUnixThemeDBusListener());
Q_ASSERT(dbus);
// Wrap slot in a lambda to avoid inheriting QKdeThemePrivate from QObject
- auto wrapper = [this](QGenericUnixThemeDBusListener::SettingType type, const QString &value) {
- settingChangedHandler(type, value);
+ auto wrapper = [this](QGenericUnixThemeDBusListener::Provider provider,
+ QGenericUnixThemeDBusListener::Setting setting,
+ const QString &value) {
+ settingChangedHandler(provider, setting, value);
};
- return QObject::connect(dbus.get(), &QGenericUnixThemeDBusListener::settingChanged, wrapper);
+ return QObject::connect(dbus.get(), &QGenericUnixThemeDBusListener::settingChanged, dbus.get(), wrapper);
}
#endif // QT_NO_DBUS
@@ -431,9 +676,136 @@ QKdeThemePrivate::QKdeThemePrivate(const QStringList &kdeDirs, int kdeVersion)
#endif // QT_NO_DBUS
}
+static constexpr QLatin1StringView settingsPrefix(QKdeThemePrivate::KdeSettingType type)
+{
+ switch (type) {
+ case QKdeThemePrivate::KdeSettingType::Root:
+ return QLatin1StringView();
+ case QKdeThemePrivate::KdeSettingType::KDE:
+ return QLatin1StringView("KDE/");
+ case QKdeThemePrivate::KdeSettingType::Fonts:
+ return QLatin1StringView();
+ case QKdeThemePrivate::KdeSettingType::Colors:
+ return QLatin1StringView("Colors:");
+ case QKdeThemePrivate::KdeSettingType::Icons:
+ return QLatin1StringView("Icons/");
+ case QKdeThemePrivate::KdeSettingType::ToolBarIcons:
+ return QLatin1StringView("ToolbarIcons/");
+ case QKdeThemePrivate::KdeSettingType::ToolBarStyle:
+ return QLatin1StringView("Toolbar style/");
+ }
+ Q_UNREACHABLE_RETURN(QLatin1StringView());
+}
+
+static constexpr QKdeThemePrivate::KdeSettingType settingsType(QKdeThemePrivate::KdeSetting setting)
+{
+#define CASE(s, type) case QKdeThemePrivate::KdeSetting::s:\
+ return QKdeThemePrivate::KdeSettingType::type
+
+ switch (setting) {
+ CASE(WidgetStyle, Root);
+ CASE(ColorScheme, Root);
+ CASE(SingleClick, KDE);
+ CASE(ShowIconsOnPushButtons, KDE);
+ CASE(IconTheme, Icons);
+ CASE(ToolBarIconSize, ToolBarIcons);
+ CASE(ToolButtonStyle, ToolBarStyle);
+ CASE(WheelScrollLines, KDE);
+ CASE(DoubleClickInterval, KDE);
+ CASE(StartDragDistance, KDE);
+ CASE(StartDragTime, KDE);
+ CASE(CursorBlinkRate, KDE);
+ CASE(Font, Root);
+ CASE(Fixed, Root);
+ CASE(MenuFont, Root);
+ CASE(ToolBarFont, Root);
+ CASE(ButtonBackground, Colors);
+ CASE(WindowBackground, Colors);
+ CASE(ViewForeground, Colors);
+ CASE(WindowForeground, Colors);
+ CASE(ViewBackground, Colors);
+ CASE(SelectionBackground, Colors);
+ CASE(SelectionForeground, Colors);
+ CASE(ViewBackgroundAlternate, Colors);
+ CASE(ButtonForeground, Colors);
+ CASE(ViewForegroundLink, Colors);
+ CASE(ViewForegroundVisited, Colors);
+ CASE(TooltipBackground, Colors);
+ CASE(TooltipForeground, Colors);
+ };
+ Q_UNREACHABLE_RETURN(QKdeThemePrivate::KdeSettingType::Root);
+}
+#undef CASE
+
+static constexpr QLatin1StringView settingsKey(QKdeThemePrivate::KdeSetting setting)
+{
+ switch (setting) {
+ case QKdeThemePrivate::KdeSetting::WidgetStyle:
+ return QLatin1StringView("widgetStyle");
+ case QKdeThemePrivate::KdeSetting::ColorScheme:
+ return QLatin1StringView("ColorScheme");
+ case QKdeThemePrivate::KdeSetting::SingleClick:
+ return QLatin1StringView("SingleClick");
+ case QKdeThemePrivate::KdeSetting::ShowIconsOnPushButtons:
+ return QLatin1StringView("ShowIconsOnPushButtons");
+ case QKdeThemePrivate::KdeSetting::IconTheme:
+ return QLatin1StringView("Theme");
+ case QKdeThemePrivate::KdeSetting::ToolBarIconSize:
+ return QLatin1StringView("Size");
+ case QKdeThemePrivate::KdeSetting::ToolButtonStyle:
+ return QLatin1StringView("ToolButtonStyle");
+ case QKdeThemePrivate::KdeSetting::WheelScrollLines:
+ return QLatin1StringView("WheelScrollLines");
+ case QKdeThemePrivate::KdeSetting::DoubleClickInterval:
+ return QLatin1StringView("DoubleClickInterval");
+ case QKdeThemePrivate::KdeSetting::StartDragDistance:
+ return QLatin1StringView("StartDragDist");
+ case QKdeThemePrivate::KdeSetting::StartDragTime:
+ return QLatin1StringView("StartDragTime");
+ case QKdeThemePrivate::KdeSetting::CursorBlinkRate:
+ return QLatin1StringView("CursorBlinkRate");
+ case QKdeThemePrivate::KdeSetting::Font:
+ return QLatin1StringView("font");
+ case QKdeThemePrivate::KdeSetting::Fixed:
+ return QLatin1StringView("fixed");
+ case QKdeThemePrivate::KdeSetting::MenuFont:
+ return QLatin1StringView("menuFont");
+ case QKdeThemePrivate::KdeSetting::ToolBarFont:
+ return QLatin1StringView("toolBarFont");
+ case QKdeThemePrivate::KdeSetting::ButtonBackground:
+ return QLatin1StringView("Button/BackgroundNormal");
+ case QKdeThemePrivate::KdeSetting::WindowBackground:
+ return QLatin1StringView("Window/BackgroundNormal");
+ case QKdeThemePrivate::KdeSetting::ViewForeground:
+ return QLatin1StringView("View/ForegroundNormal");
+ case QKdeThemePrivate::KdeSetting::WindowForeground:
+ return QLatin1StringView("Window/ForegroundNormal");
+ case QKdeThemePrivate::KdeSetting::ViewBackground:
+ return QLatin1StringView("View/BackgroundNormal");
+ case QKdeThemePrivate::KdeSetting::SelectionBackground:
+ return QLatin1StringView("Selection/BackgroundNormal");
+ case QKdeThemePrivate::KdeSetting::SelectionForeground:
+ return QLatin1StringView("Selection/ForegroundNormal");
+ case QKdeThemePrivate::KdeSetting::ViewBackgroundAlternate:
+ return QLatin1StringView("View/BackgroundAlternate");
+ case QKdeThemePrivate::KdeSetting::ButtonForeground:
+ return QLatin1StringView("Button/ForegroundNormal");
+ case QKdeThemePrivate::KdeSetting::ViewForegroundLink:
+ return QLatin1StringView("View/ForegroundLink");
+ case QKdeThemePrivate::KdeSetting::ViewForegroundVisited:
+ return QLatin1StringView("View/ForegroundVisited");
+ case QKdeThemePrivate::KdeSetting::TooltipBackground:
+ return QLatin1StringView("Tooltip/BackgroundNormal");
+ case QKdeThemePrivate::KdeSetting::TooltipForeground:
+ return QLatin1StringView("Tooltip/ForegroundNormal");
+ };
+ Q_UNREACHABLE_RETURN(QLatin1StringView());
+}
+
void QKdeThemePrivate::refresh()
{
resources.clear();
+ clearKdeSettings();
toolButtonStyle = Qt::ToolButtonTextBesideIcon;
toolBarIconSize = 0;
@@ -446,45 +818,39 @@ void QKdeThemePrivate::refresh()
else
iconFallbackThemeName = iconThemeName = QStringLiteral("oxygen");
- QHash<QString, QSettings*> kdeSettings;
-
QPalette systemPalette = QPalette();
readKdeSystemPalette(kdeDirs, kdeVersion, kdeSettings, &systemPalette);
resources.palettes[QPlatformTheme::SystemPalette] = new QPalette(systemPalette);
//## TODO tooltip color
- const QVariant styleValue = readKdeSetting(QStringLiteral("widgetStyle"), kdeDirs, kdeVersion, kdeSettings);
+ const QVariant styleValue = readKdeSetting(KdeSetting::WidgetStyle);
if (styleValue.isValid()) {
const QString style = styleValue.toString();
if (style != styleNames.front())
styleNames.push_front(style);
}
- const QVariant colorScheme = readKdeSetting(QStringLiteral("ColorScheme"), kdeDirs,
- kdeVersion, kdeSettings);
+ const QVariant colorScheme = readKdeSetting(KdeSetting::ColorScheme);
- if (colorScheme.isValid())
- updateAppearance(colorScheme.toString());
- else
- m_appearance = Qt::Appearance::Unknown;
+ updateColorScheme(colorScheme.toString());
- const QVariant singleClickValue = readKdeSetting(QStringLiteral("KDE/SingleClick"), kdeDirs, kdeVersion, kdeSettings);
+ const QVariant singleClickValue = readKdeSetting(KdeSetting::SingleClick);
if (singleClickValue.isValid())
singleClick = singleClickValue.toBool();
- const QVariant showIconsOnPushButtonsValue = readKdeSetting(QStringLiteral("KDE/ShowIconsOnPushButtons"), kdeDirs, kdeVersion, kdeSettings);
+ const QVariant showIconsOnPushButtonsValue = readKdeSetting(KdeSetting::ShowIconsOnPushButtons);
if (showIconsOnPushButtonsValue.isValid())
showIconsOnPushButtons = showIconsOnPushButtonsValue.toBool();
- const QVariant themeValue = readKdeSetting(QStringLiteral("Icons/Theme"), kdeDirs, kdeVersion, kdeSettings);
+ const QVariant themeValue = readKdeSetting(KdeSetting::IconTheme);
if (themeValue.isValid())
iconThemeName = themeValue.toString();
- const QVariant toolBarIconSizeValue = readKdeSetting(QStringLiteral("ToolbarIcons/Size"), kdeDirs, kdeVersion, kdeSettings);
+ const QVariant toolBarIconSizeValue = readKdeSetting(KdeSetting::ToolBarIconSize);
if (toolBarIconSizeValue.isValid())
toolBarIconSize = toolBarIconSizeValue.toInt();
- const QVariant toolbarStyleValue = readKdeSetting(QStringLiteral("Toolbar style/ToolButtonStyle"), kdeDirs, kdeVersion, kdeSettings);
+ const QVariant toolbarStyleValue = readKdeSetting(KdeSetting::ToolButtonStyle);
if (toolbarStyleValue.isValid()) {
const QString toolBarStyle = toolbarStyleValue.toString();
if (toolBarStyle == "TextBesideIcon"_L1)
@@ -495,35 +861,35 @@ void QKdeThemePrivate::refresh()
toolButtonStyle = Qt::ToolButtonTextUnderIcon;
}
- const QVariant wheelScrollLinesValue = readKdeSetting(QStringLiteral("KDE/WheelScrollLines"), kdeDirs, kdeVersion, kdeSettings);
+ const QVariant wheelScrollLinesValue = readKdeSetting(KdeSetting::WheelScrollLines);
if (wheelScrollLinesValue.isValid())
wheelScrollLines = wheelScrollLinesValue.toInt();
- const QVariant doubleClickIntervalValue = readKdeSetting(QStringLiteral("KDE/DoubleClickInterval"), kdeDirs, kdeVersion, kdeSettings);
+ const QVariant doubleClickIntervalValue = readKdeSetting(KdeSetting::DoubleClickInterval);
if (doubleClickIntervalValue.isValid())
doubleClickInterval = doubleClickIntervalValue.toInt();
- const QVariant startDragDistValue = readKdeSetting(QStringLiteral("KDE/StartDragDist"), kdeDirs, kdeVersion, kdeSettings);
+ const QVariant startDragDistValue = readKdeSetting(KdeSetting::StartDragDistance);
if (startDragDistValue.isValid())
startDragDist = startDragDistValue.toInt();
- const QVariant startDragTimeValue = readKdeSetting(QStringLiteral("KDE/StartDragTime"), kdeDirs, kdeVersion, kdeSettings);
+ const QVariant startDragTimeValue = readKdeSetting(KdeSetting::StartDragTime);
if (startDragTimeValue.isValid())
startDragTime = startDragTimeValue.toInt();
- const QVariant cursorBlinkRateValue = readKdeSetting(QStringLiteral("KDE/CursorBlinkRate"), kdeDirs, kdeVersion, kdeSettings);
+ const QVariant cursorBlinkRateValue = readKdeSetting(KdeSetting::CursorBlinkRate);
if (cursorBlinkRateValue.isValid()) {
cursorBlinkRate = cursorBlinkRateValue.toInt();
cursorBlinkRate = cursorBlinkRate > 0 ? qBound(200, cursorBlinkRate, 2000) : 0;
}
// Read system font, ignore 'smallestReadableFont'
- if (QFont *systemFont = kdeFont(readKdeSetting(QStringLiteral("font"), kdeDirs, kdeVersion, kdeSettings)))
+ if (QFont *systemFont = kdeFont(readKdeSetting(KdeSetting::Font)))
resources.fonts[QPlatformTheme::SystemFont] = systemFont;
else
resources.fonts[QPlatformTheme::SystemFont] = new QFont(QLatin1StringView(defaultSystemFontNameC), defaultSystemFontSize);
- if (QFont *fixedFont = kdeFont(readKdeSetting(QStringLiteral("fixed"), kdeDirs, kdeVersion, kdeSettings))) {
+ if (QFont *fixedFont = kdeFont(readKdeSetting(KdeSetting::Fixed))) {
resources.fonts[QPlatformTheme::FixedFont] = fixedFont;
} else {
fixedFont = new QFont(QLatin1StringView(defaultFixedFontNameC), defaultSystemFontSize);
@@ -531,12 +897,12 @@ void QKdeThemePrivate::refresh()
resources.fonts[QPlatformTheme::FixedFont] = fixedFont;
}
- if (QFont *menuFont = kdeFont(readKdeSetting(QStringLiteral("menuFont"), kdeDirs, kdeVersion, kdeSettings))) {
+ if (QFont *menuFont = kdeFont(readKdeSetting(KdeSetting::MenuFont))) {
resources.fonts[QPlatformTheme::MenuFont] = menuFont;
resources.fonts[QPlatformTheme::MenuBarFont] = new QFont(*menuFont);
}
- if (QFont *toolBarFont = kdeFont(readKdeSetting(QStringLiteral("toolBarFont"), kdeDirs, kdeVersion, kdeSettings)))
+ if (QFont *toolBarFont = kdeFont(readKdeSetting(KdeSetting::ToolBarFont)))
resources.fonts[QPlatformTheme::ToolButtonFont] = toolBarFont;
QWindowSystemInterface::handleThemeChange();
@@ -546,7 +912,7 @@ void QKdeThemePrivate::refresh()
qDeleteAll(kdeSettings);
}
-QVariant QKdeThemePrivate::readKdeSetting(const QString &key, const QStringList &kdeDirs, int kdeVersion, QHash<QString, QSettings*> &kdeSettings)
+QVariant QKdeThemePrivate::readKdeSetting(KdeSetting s, const QStringList &kdeDirs, int kdeVersion, QHash<QString, QSettings*> &kdeSettings)
{
for (const QString &kdeDir : kdeDirs) {
QSettings *settings = kdeSettings.value(kdeDir);
@@ -558,6 +924,7 @@ QVariant QKdeThemePrivate::readKdeSetting(const QString &key, const QStringList
}
}
if (settings) {
+ const QString key = settingsPrefix(settingsType(s)) + settingsKey(s);
const QVariant value = settings->value(key);
if (value.isValid())
return value;
@@ -566,6 +933,16 @@ QVariant QKdeThemePrivate::readKdeSetting(const QString &key, const QStringList
return QVariant();
}
+QVariant QKdeThemePrivate::readKdeSetting(KdeSetting s) const
+{
+ return readKdeSetting(s, kdeDirs, kdeVersion, kdeSettings);
+}
+
+void QKdeThemePrivate::clearKdeSettings() const
+{
+ kdeSettings.clear();
+}
+
// Reads the color from the KDE configuration, and store it in the
// palette with the given color role if found.
static inline bool kdeColor(QPalette *pal, QPalette::ColorRole role, const QVariant &value)
@@ -581,7 +958,7 @@ static inline bool kdeColor(QPalette *pal, QPalette::ColorRole role, const QVari
void QKdeThemePrivate::readKdeSystemPalette(const QStringList &kdeDirs, int kdeVersion, QHash<QString, QSettings*> &kdeSettings, QPalette *pal)
{
- if (!kdeColor(pal, QPalette::Button, readKdeSetting(QStringLiteral("Colors:Button/BackgroundNormal"), kdeDirs, kdeVersion, kdeSettings))) {
+ if (!kdeColor(pal, QPalette::Button, readKdeSetting(KdeSetting::ButtonBackground, kdeDirs, kdeVersion, kdeSettings))) {
// kcolorscheme.cpp: SetDefaultColors
const QColor defaultWindowBackground(214, 210, 208);
const QColor defaultButtonBackground(223, 220, 217);
@@ -589,18 +966,18 @@ void QKdeThemePrivate::readKdeSystemPalette(const QStringList &kdeDirs, int kdeV
return;
}
- kdeColor(pal, QPalette::Window, readKdeSetting(QStringLiteral("Colors:Window/BackgroundNormal"), kdeDirs, kdeVersion, kdeSettings));
- kdeColor(pal, QPalette::Text, readKdeSetting(QStringLiteral("Colors:View/ForegroundNormal"), kdeDirs, kdeVersion, kdeSettings));
- kdeColor(pal, QPalette::WindowText, readKdeSetting(QStringLiteral("Colors:Window/ForegroundNormal"), kdeDirs, kdeVersion, kdeSettings));
- kdeColor(pal, QPalette::Base, readKdeSetting(QStringLiteral("Colors:View/BackgroundNormal"), kdeDirs, kdeVersion, kdeSettings));
- kdeColor(pal, QPalette::Highlight, readKdeSetting(QStringLiteral("Colors:Selection/BackgroundNormal"), kdeDirs, kdeVersion, kdeSettings));
- kdeColor(pal, QPalette::HighlightedText, readKdeSetting(QStringLiteral("Colors:Selection/ForegroundNormal"), kdeDirs, kdeVersion, kdeSettings));
- kdeColor(pal, QPalette::AlternateBase, readKdeSetting(QStringLiteral("Colors:View/BackgroundAlternate"), kdeDirs, kdeVersion, kdeSettings));
- kdeColor(pal, QPalette::ButtonText, readKdeSetting(QStringLiteral("Colors:Button/ForegroundNormal"), kdeDirs, kdeVersion, kdeSettings));
- kdeColor(pal, QPalette::Link, readKdeSetting(QStringLiteral("Colors:View/ForegroundLink"), kdeDirs, kdeVersion, kdeSettings));
- kdeColor(pal, QPalette::LinkVisited, readKdeSetting(QStringLiteral("Colors:View/ForegroundVisited"), kdeDirs, kdeVersion, kdeSettings));
- kdeColor(pal, QPalette::ToolTipBase, readKdeSetting(QStringLiteral("Colors:Tooltip/BackgroundNormal"), kdeDirs, kdeVersion, kdeSettings));
- kdeColor(pal, QPalette::ToolTipText, readKdeSetting(QStringLiteral("Colors:Tooltip/ForegroundNormal"), kdeDirs, kdeVersion, kdeSettings));
+ kdeColor(pal, QPalette::Window, readKdeSetting(KdeSetting::WindowBackground, kdeDirs, kdeVersion, kdeSettings));
+ kdeColor(pal, QPalette::Text, readKdeSetting(KdeSetting::ViewForeground, kdeDirs, kdeVersion, kdeSettings));
+ kdeColor(pal, QPalette::WindowText, readKdeSetting(KdeSetting::WindowForeground, kdeDirs, kdeVersion, kdeSettings));
+ kdeColor(pal, QPalette::Base, readKdeSetting(KdeSetting::ViewBackground, kdeDirs, kdeVersion, kdeSettings));
+ kdeColor(pal, QPalette::Highlight, readKdeSetting(KdeSetting::SelectionBackground, kdeDirs, kdeVersion, kdeSettings));
+ kdeColor(pal, QPalette::HighlightedText, readKdeSetting(KdeSetting::SelectionForeground, kdeDirs, kdeVersion, kdeSettings));
+ kdeColor(pal, QPalette::AlternateBase, readKdeSetting(KdeSetting::ViewBackgroundAlternate, kdeDirs, kdeVersion, kdeSettings));
+ kdeColor(pal, QPalette::ButtonText, readKdeSetting(KdeSetting::ButtonForeground, kdeDirs, kdeVersion, kdeSettings));
+ kdeColor(pal, QPalette::Link, readKdeSetting(KdeSetting::ViewForegroundLink, kdeDirs, kdeVersion, kdeSettings));
+ kdeColor(pal, QPalette::LinkVisited, readKdeSetting(KdeSetting::ViewForegroundVisited, kdeDirs, kdeVersion, kdeSettings));
+ kdeColor(pal, QPalette::ToolTipBase, readKdeSetting(KdeSetting::TooltipBackground, kdeDirs, kdeVersion, kdeSettings));
+ kdeColor(pal, QPalette::ToolTipText, readKdeSetting(KdeSetting::TooltipForeground, kdeDirs, kdeVersion, kdeSettings));
// The above code sets _all_ color roles to "normal" colors. In KDE, the disabled
// color roles are calculated by applying various effects described in kdeglobals.
@@ -733,6 +1110,8 @@ QVariant QKdeTheme::themeHint(QPlatformTheme::ThemeHint hint) const
return QVariant(mouseCursorTheme());
case QPlatformTheme::MouseCursorSize:
return QVariant(mouseCursorSize());
+ case QPlatformTheme::PreferFileIconFromTheme:
+ return true;
default:
break;
}
@@ -749,48 +1128,47 @@ QIcon QKdeTheme::fileIcon(const QFileInfo &fileInfo, QPlatformTheme::IconOptions
#endif
}
-Qt::Appearance QKdeTheme::appearance() const
+Qt::ColorScheme QKdeTheme::colorScheme() const
{
- return d_func()->m_appearance;
+ return d_func()->m_colorScheme;
}
/*!
\internal
- \brief QKdeTheme::setAppearance - guess and set appearance for unix themes.
- KDE themes do not have an appearance property.
- The key words "dark" or "light" should be part of the theme name.
+ \brief QKdeTheme::updateColorScheme - guess and set a color scheme for unix themes.
+ KDE themes do not have a color scheme property.
+ The key words "dark" or "light" are usually part of the theme name.
This is, however, not a mandatory convention.
- If \param themeName contains a key word, the respective appearance is set.
- If it doesn't, the appearance is heuristically determined by comparing text and base color
+ If \param themeName contains a valid key word, the respective color scheme is set.
+ If it doesn't, the color scheme is heuristically determined by comparing text and base color
of the system palette.
*/
-void QKdeThemePrivate::updateAppearance(const QString &themeName)
+void QKdeThemePrivate::updateColorScheme(const QString &themeName)
{
if (themeName.contains(QLatin1StringView("light"), Qt::CaseInsensitive)) {
- m_appearance = Qt::Appearance::Light;
+ m_colorScheme = Qt::ColorScheme::Light;
return;
}
if (themeName.contains(QLatin1StringView("dark"), Qt::CaseInsensitive)) {
- m_appearance = Qt::Appearance::Dark;
+ m_colorScheme = Qt::ColorScheme::Dark;
return;
}
if (systemPalette) {
if (systemPalette->text().color().lightness() < systemPalette->base().color().lightness()) {
- m_appearance = Qt::Appearance::Light;
+ m_colorScheme = Qt::ColorScheme::Light;
return;
}
if (systemPalette->text().color().lightness() > systemPalette->base().color().lightness()) {
- m_appearance = Qt::Appearance::Dark;
+ m_colorScheme = Qt::ColorScheme::Dark;
return;
}
}
- m_appearance = Qt::Appearance::Unknown;
+ m_colorScheme = Qt::ColorScheme::Unknown;
}
-
const QPalette *QKdeTheme::palette(Palette type) const
{
Q_D(const QKdeTheme);
@@ -870,7 +1248,7 @@ QPlatformMenuBar *QKdeTheme::createPlatformMenuBar() const
#if !defined(QT_NO_DBUS) && !defined(QT_NO_SYSTEMTRAYICON)
QPlatformSystemTrayIcon *QKdeTheme::createPlatformSystemTrayIcon() const
{
- if (isDBusTrayAvailable())
+ if (shouldUseDBusTray())
return new QDBusTrayIcon();
return nullptr;
}
@@ -911,11 +1289,11 @@ public:
mutable QFont *fixedFont = nullptr;
#ifndef QT_NO_DBUS
- Qt::Appearance m_appearance = Qt::Appearance::Unknown;
+ Qt::ColorScheme m_colorScheme = Qt::ColorScheme::Unknown;
private:
std::unique_ptr<QGenericUnixThemeDBusListener> dbus;
bool initDbus();
- void updateAppearance(const QString &themeName);
+ void updateColorScheme(const QString &themeName);
#endif // QT_NO_DBUS
};
@@ -936,35 +1314,37 @@ QGnomeThemePrivate::~QGnomeThemePrivate()
#ifndef QT_NO_DBUS
bool QGnomeThemePrivate::initDbus()
{
- static constexpr QLatin1StringView service("");
- static constexpr QLatin1StringView path("/org/freedesktop/portal/desktop");
- static constexpr QLatin1StringView interface("org.freedesktop.portal.Settings");
- static constexpr QLatin1StringView signal("SettingChanged");
- dbus.reset(new QGenericUnixThemeDBusListener(service, path, interface, signal));
+ dbus.reset(new QGenericUnixThemeDBusListener());
Q_ASSERT(dbus);
// Wrap slot in a lambda to avoid inheriting QGnomeThemePrivate from QObject
- auto wrapper = [this](QGenericUnixThemeDBusListener::SettingType type, const QString &value) {
- if (type == QGenericUnixThemeDBusListener::SettingType::GtkTheme)
- updateAppearance(value);
- };
+ auto wrapper = [this](QGenericUnixThemeDBusListener::Provider provider,
+ QGenericUnixThemeDBusListener::Setting setting,
+ const QString &value) {
+ if (provider != QGenericUnixThemeDBusListener::Provider::Gnome
+ && provider != QGenericUnixThemeDBusListener::Provider::Gtk) {
+ return;
+ }
- return QObject::connect(dbus.get(), &QGenericUnixThemeDBusListener::settingChanged, wrapper);
+ if (setting == QGenericUnixThemeDBusListener::Setting::Theme)
+ updateColorScheme(value);
+ };
+ return QObject::connect(dbus.get(), &QGenericUnixThemeDBusListener::settingChanged, dbus.get(), wrapper);
}
-void QGnomeThemePrivate::updateAppearance(const QString &themeName)
+void QGnomeThemePrivate::updateColorScheme(const QString &themeName)
{
- const auto oldAppearance = m_appearance;
+ const auto oldColorScheme = m_colorScheme;
if (themeName.contains(QLatin1StringView("light"), Qt::CaseInsensitive)) {
- m_appearance = Qt::Appearance::Light;
+ m_colorScheme = Qt::ColorScheme::Light;
} else if (themeName.contains(QLatin1StringView("dark"), Qt::CaseInsensitive)) {
- m_appearance = Qt::Appearance::Dark;
+ m_colorScheme = Qt::ColorScheme::Dark;
} else {
- m_appearance = Qt::Appearance::Unknown;
+ m_colorScheme = Qt::ColorScheme::Unknown;
}
- if (oldAppearance != m_appearance)
+ if (oldColorScheme != m_colorScheme)
QWindowSystemInterface::handleThemeChange();
}
#endif // QT_NO_DBUS
@@ -1009,6 +1389,8 @@ QVariant QGnomeTheme::themeHint(QPlatformTheme::ThemeHint hint) const
return QVariant(mouseCursorTheme());
case QPlatformTheme::MouseCursorSize:
return QVariant(mouseCursorSize());
+ case QPlatformTheme::PreferFileIconFromTheme:
+ return true;
default:
break;
}
@@ -1053,9 +1435,9 @@ QPlatformMenuBar *QGnomeTheme::createPlatformMenuBar() const
return nullptr;
}
-Qt::Appearance QGnomeTheme::appearance() const
+Qt::ColorScheme QGnomeTheme::colorScheme() const
{
- return d_func()->m_appearance;
+ return d_func()->m_colorScheme;
}
#endif
@@ -1063,7 +1445,7 @@ Qt::Appearance QGnomeTheme::appearance() const
#if !defined(QT_NO_DBUS) && !defined(QT_NO_SYSTEMTRAYICON)
QPlatformSystemTrayIcon *QGnomeTheme::createPlatformSystemTrayIcon() const
{
- if (isDBusTrayAvailable())
+ if (shouldUseDBusTray())
return new QDBusTrayIcon();
return nullptr;
}