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.cpp155
1 files changed, 150 insertions, 5 deletions
diff --git a/src/gui/platform/unix/qgenericunixthemes.cpp b/src/gui/platform/unix/qgenericunixthemes.cpp
index d90d5de098..1efd759bcf 100644
--- a/src/gui/platform/unix/qgenericunixthemes.cpp
+++ b/src/gui/platform/unix/qgenericunixthemes.cpp
@@ -41,6 +41,9 @@
#include <algorithm>
QT_BEGIN_NAMESPACE
+#ifndef QT_NO_DBUS
+Q_LOGGING_CATEGORY(lcQpaThemeDBus, "qt.qpa.theme.dbus")
+#endif
using namespace Qt::StringLiterals;
@@ -98,7 +101,92 @@ static bool isDBusGlobalMenuAvailable()
static bool dbusGlobalMenuAvailable = checkDBusGlobalMenuAvailable();
return dbusGlobalMenuAvailable;
}
-#endif
+
+/*!
+ * \internal
+ * The QGenericUnixThemeDBusListener class listens to the SettingChanged DBus signal
+ * and translates it into the QDbusSettingType enum.
+ * 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.
+ * It is emitted on known setting types only.
+ */
+
+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,
+ Unknown
+ };
+ Q_ENUM(SettingType)
+
+ static SettingType toSettingType(const QString &location, const QString &key);
+
+private Q_SLOTS:
+ void onSettingChanged(const QString &location, const QString &key, const QDBusVariant &value);
+
+Q_SIGNALS:
+ void settingChanged(QGenericUnixThemeDBusListener::SettingType type, const QString &value);
+
+};
+
+QGenericUnixThemeDBusListener::QGenericUnixThemeDBusListener(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) {
+ qRegisterMetaType<QDBusVariant>();
+ dBusSignalConnected = dbus.connect(service, path, interface, signal, this,
+ SLOT(onSettingChanged(QString,QString,QDBusVariant)));
+ }
+
+ if (dBusSignalConnected) {
+ // Connection successful
+ qCDebug(lcQpaThemeDBus) << LOG;
+ } else {
+ if (dBusRunning) {
+ // DBus running, but connection failed
+ qCWarning(lcQpaThemeDBus) << "DBus connection failed:" << LOG;
+ } else {
+ // DBus not running
+ qCWarning(lcQpaThemeDBus) << "Session DBus not running.";
+ }
+ qCWarning(lcQpaThemeDBus) << "Application will not react to KDE setting changes.\n"
+ << "Check your DBus installation.";
+ }
+#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;
+ return SettingType::Unknown;
+}
+
+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());
+}
+
+#endif //QT_NO_DBUS
class QGenericUnixThemePrivate : public QPlatformThemePrivate
{
@@ -231,11 +319,9 @@ static QIcon xdgFileIcon(const QFileInfo &fileInfo)
#if QT_CONFIG(settings)
class QKdeThemePrivate : public QPlatformThemePrivate
{
+
public:
- QKdeThemePrivate(const QStringList &kdeDirs, int kdeVersion)
- : kdeDirs(kdeDirs)
- , kdeVersion(kdeVersion)
- { }
+ QKdeThemePrivate(const QStringList &kdeDirs, int kdeVersion);
static QString kdeGlobals(const QString &kdeDir, int kdeVersion)
{
@@ -266,8 +352,59 @@ public:
int startDragDist = 10;
int startDragTime = 500;
int cursorBlinkRate = 1000;
+
+#ifndef QT_NO_DBUS
+private:
+ std::unique_ptr<QGenericUnixThemeDBusListener> dbus;
+ bool initDbus();
+ void settingChangedHandler(QGenericUnixThemeDBusListener::SettingType type, const QString &value);
+#endif // QT_NO_DBUS
};
+#ifndef QT_NO_DBUS
+void QKdeThemePrivate::settingChangedHandler(QGenericUnixThemeDBusListener::SettingType type, const QString &value)
+{
+ switch (type) {
+ case QGenericUnixThemeDBusListener::SettingType::KdeGlobalTheme:
+ qCDebug(lcQpaThemeDBus) << "KDE global theme changed to:" << value;
+ break;
+ case QGenericUnixThemeDBusListener::SettingType::KdeApplicationStyle:
+ qCDebug(lcQpaThemeDBus) << "KDE application style changed to:" << value;
+ break;
+ case QGenericUnixThemeDBusListener::SettingType::Unknown:
+ Q_UNREACHABLE();
+ }
+
+ refresh();
+}
+
+bool QKdeThemePrivate::initDbus()
+{
+ constexpr QLatin1StringView service("");
+ constexpr QLatin1StringView path("/org/freedesktop/portal/desktop");
+ constexpr QLatin1StringView interface("org.freedesktop.portal.Settings");
+ constexpr QLatin1StringView signal("SettingChanged");
+
+ dbus.reset(new QGenericUnixThemeDBusListener(service, path, interface, signal));
+ 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);
+ };
+
+ return QObject::connect(dbus.get(), &QGenericUnixThemeDBusListener::settingChanged, wrapper);
+}
+#endif // QT_NO_DBUS
+
+QKdeThemePrivate::QKdeThemePrivate(const QStringList &kdeDirs, int kdeVersion)
+ : kdeDirs(kdeDirs), kdeVersion(kdeVersion)
+{
+#ifndef QT_NO_DBUS
+ initDbus();
+#endif // QT_NO_DBUS
+}
+
void QKdeThemePrivate::refresh()
{
resources.clear();
@@ -368,6 +505,8 @@ void QKdeThemePrivate::refresh()
if (QFont *toolBarFont = kdeFont(readKdeSetting(QStringLiteral("toolBarFont"), kdeDirs, kdeVersion, kdeSettings)))
resources.fonts[QPlatformTheme::ToolButtonFont] = toolBarFont;
+ QWindowSystemInterface::handleThemeChange();
+
qCDebug(lcQpaFonts) << "default fonts: system" << resources.fonts[QPlatformTheme::SystemFont]
<< "fixed" << resources.fonts[QPlatformTheme::FixedFont];
qDeleteAll(kdeSettings);
@@ -726,6 +865,8 @@ QVariant QGnomeTheme::themeHint(QPlatformTheme::ThemeHint hint) const
case QPlatformTheme::ButtonPressKeys:
return QVariant::fromValue(
QList<Qt::Key>({ Qt::Key_Space, Qt::Key_Return, Qt::Key_Enter, Qt::Key_Select }));
+ case QPlatformTheme::PreselectFirstFileInDirectory:
+ return true;
default:
break;
}
@@ -853,3 +994,7 @@ QStringList QGenericUnixTheme::themeNames()
}
QT_END_NAMESPACE
+
+#ifndef QT_NO_DBUS
+#include "qgenericunixthemes.moc"
+#endif // QT_NO_DBUS