Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qgnomeportalinterface.cpp
Go to the documentation of this file.
1// Copyright (C) 2025 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
7#include <private/qdbusplatformmenu_p.h>
8#include <QtDBus/QDBusMessage>
9#include <QtDBus/QDBusPendingCall>
10#include <QtDBus/QDBusReply>
11#include <QtDBus/QDBusVariant>
12
14
15#if QT_CONFIG(dbus)
16Q_STATIC_LOGGING_CATEGORY(lcQpaThemeGnome, "qt.qpa.theme.gnome")
17#endif // QT_CONFIG(dbus)
18
19using namespace Qt::StringLiterals;
20
21QGnomePortalInterface::QGnomePortalInterface(QObject *parent)
22 : QObject(parent), m_dbus{ new QDBusListener }
23{
24 QObject::connect(m_dbus.get(), &QDBusListener::settingChanged, this,
25 &QGnomePortalInterface::dbusSettingChanged);
26
27 querySettings();
28}
29
30/*!
31 \internal
32 \brief QGnomePortalInterface::colorScheme
33 This is a getter method for the color-scheme loaded from the DBus portal.
34 \param fallback indicates the fallback color-scheme.
35 \return returns the cached color-scheme. If the color-scheme was not loaded
36 it returns the \a fallback color-scheme.
37 */
38Qt::ColorScheme QGnomePortalInterface::colorScheme(Qt::ColorScheme fallback) const
39{
40 if (!m_colorScheme.has_value())
41 return fallback;
42 return m_colorScheme.value();
43}
44
45/*!
46 \internal
47 \brief QGnomePortalInterface::contrastPreference
48 This is a getter method for the contrast-preference loaded from the DBus portal.
49 \param fallback indicates the fallback contrast-preference.
50 \return returns the cached contrast-preference if it was loaded. Otherwise,
51 returns the \a fallback contrast-preference.
52 */
53Qt::ContrastPreference
54QGnomePortalInterface::contrastPreference(Qt::ContrastPreference fallback) const
55{
56 if (!m_contrast.has_value())
57 return fallback;
58 return m_contrast.value();
59}
60
61void QGnomePortalInterface::querySettings()
62{
63 QDBusConnection dbus = QDBusConnection::sessionBus();
64 if (!dbus.isConnected()) {
65 qCWarning(lcQpaThemeGnome) << "dbus connection failed. Last error: " << dbus.lastError();
66 return;
67 }
68
69 constexpr auto method = "ReadAll"_L1;
70 auto message = QDBusMessage::createMethodCall(s_service, s_path, s_interface, method);
71
72 message << QStringList{ QDBusSettings::XdgSettings::AppearanceNamespace,
73 QDBusSettings::GnomeSettings::AllyNamespace };
74
75 QDBusPendingCall pendingCall = dbus.asyncCall(message);
76 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall, this);
77
78 auto onWatcherFinished = [&](QDBusPendingCallWatcher *watcher) {
79 const QDBusMessage reply = watcher->reply();
80 if (QDBusMessage::ErrorMessage == reply.type()) {
81 qCWarning(lcQpaThemeGnome)
82 << "dbus reply error: [" << reply.errorName() << "]" << reply.errorMessage();
83 watcher->deleteLater();
84 return;
85 }
86
87 const auto convertXdgColorScheme = [](const QVariant &value) {
88 using namespace QDBusSettings::XdgSettings;
89 return QVariant::fromValue(convertColorScheme(value));
90 };
91
92 constexpr auto XdgContrastKey = QDBusSettings::XdgSettings::ContrastKey;
93 const auto convertXdgContrast = [](const QVariant &value) {
94 using namespace QDBusSettings::XdgSettings;
95 return QVariant::fromValue(convertContrastPreference(value));
96 };
97
98 constexpr auto GnomeContrastKey = QDBusSettings::GnomeSettings::ContrastKey;
99 const auto convrtGnomeContrast = [](const QVariant &value) {
100 using namespace QDBusSettings::GnomeSettings;
101 return QVariant::fromValue(convertContrastPreference(value));
102 };
103
104 const QVariantList &args = reply.arguments();
105 for (const QVariant &arg_ : args) {
106 const QMap<QString, QVariantMap> arg = qdbus_cast<QMap<QString, QVariantMap>>(arg_);
107 for (auto aIt = arg.begin(); aIt != arg.end(); ++aIt) {
108 const QString &namespace_ = aIt.key();
109 const QVariantMap &settings = aIt.value();
110 for (auto sIt = settings.begin(); sIt != settings.end(); ++sIt) {
111 const QString &key = sIt.key();
112 const QVariant &value = sIt.value();
113 if ((key == QDBusSettings::XdgSettings::ColorSchemeKey)
114 && (namespace_ == QDBusSettings::XdgSettings::AppearanceNamespace))
115 dbusSettingChanged(QDBusListener::Provider::Gnome,
116 QDBusListener::Setting::ColorScheme,
117 convertXdgColorScheme(value));
118 else if ((key == XdgContrastKey)
119 && (namespace_ == QDBusSettings::XdgSettings::AppearanceNamespace))
120 dbusSettingChanged(QDBusListener::Provider::Gnome,
121 QDBusListener::Setting::Contrast,
122 convertXdgContrast(value));
123 else if ((key == GnomeContrastKey)
124 && (namespace_ == QDBusSettings::GnomeSettings::AllyNamespace))
125 dbusSettingChanged(QDBusListener::Provider::Gnome,
126 QDBusListener::Setting::Contrast,
127 convrtGnomeContrast(value));
128 }
129 }
130 }
131 watcher->deleteLater();
132 };
133 connect(watcher, &QDBusPendingCallWatcher::finished, this, onWatcherFinished);
134}
135
136void QGnomePortalInterface::updateColorScheme(Qt::ColorScheme colorScheme)
137{
138 if (m_colorScheme.has_value() && (m_colorScheme.value() == colorScheme))
139 return;
140 m_colorScheme = colorScheme;
141 emit colorSchemeChanged(colorScheme);
142}
143
144void QGnomePortalInterface::updateContrast(Qt::ContrastPreference contrast)
145{
146 if (m_contrast.has_value() && (m_contrast.value() == contrast))
147 return;
148 m_contrast = contrast;
149 emit contrastChanged(contrast);
150}
151
152void QGnomePortalInterface::dbusSettingChanged(QDBusListener::Provider provider,
153 QDBusListener::Setting setting,
154 const QVariant &value)
155{
156 if (provider != QDBusListener::Provider::Gnome && provider != QDBusListener::Provider::Gtk)
157 return;
158
159 switch (setting) {
160 case QDBusListener::Setting::ColorScheme:
161 updateColorScheme(value.value<Qt::ColorScheme>());
162 break;
163 case QDBusListener::Setting::Contrast:
164 updateContrast(value.value<Qt::ContrastPreference>());
165 break;
166 case QDBusListener::Setting::Theme:
167 emit themeNameChanged(value.toString());
168 break;
169 default:
170 break;
171 }
172}
173
174QT_END_NAMESPACE
175
176#include "moc_qgnomeportalinterface_p.cpp"