1// Copyright (C) 2024 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
4//
5// W A R N I N G
6// -------------
7//
8// This file is not part of the Qt API. It exists purely as an
9// implementation detail. This header file may change from version to
10// version without notice, or even be removed.
11//
12// We mean it.
13//
14
15#include "qgtk3portalinterface_p.h"
16#include "qgtk3storage_p.h"
17
18#include <QtDBus/QDBusArgument>
19#include <QtDBus/QDBusConnection>
20#include <QtDBus/QDBusMessage>
21#include <QtDBus/QDBusPendingCall>
22#include <QtDBus/QDBusPendingCallWatcher>
23#include <QtDBus/QDBusPendingReply>
24#include <QtDBus/QDBusVariant>
25#include <QtDBus/QtDBus>
26
27QT_BEGIN_NAMESPACE
28
29Q_LOGGING_CATEGORY(lcQGtk3PortalInterface, "qt.qpa.gtk");
30
31using namespace Qt::StringLiterals;
32
33static constexpr QLatin1StringView appearanceInterface("org.freedesktop.appearance");
34static constexpr QLatin1StringView colorSchemeKey("color-scheme");
35
36const QDBusArgument &operator>>(const QDBusArgument &argument, QMap<QString, QVariantMap> &map)
37{
38 argument.beginMap();
39 map.clear();
40
41 while (!argument.atEnd()) {
42 QString key;
43 QVariantMap value;
44 argument.beginMapEntry();
45 argument >> key >> value;
46 argument.endMapEntry();
47 map.insert(key, value);
48 }
49
50 argument.endMap();
51 return argument;
52}
53
54QGtk3PortalInterface::QGtk3PortalInterface(QGtk3Storage *s)
55 : m_storage(s) {
56 qRegisterMetaType<QDBusVariant>();
57 qDBusRegisterMetaType<QMap<QString, QVariantMap>>();
58
59 queryColorScheme();
60
61 if (!s) {
62 qCDebug(lcQGtk3PortalInterface) << "QGtk3PortalInterface instantiated without QGtk3Storage."
63 << "No reaction to runtime theme changes.";
64 }
65}
66
67Qt::ColorScheme QGtk3PortalInterface::colorScheme() const
68{
69 return m_colorScheme;
70}
71
72void QGtk3PortalInterface::queryColorScheme() {
73 QDBusConnection connection = QDBusConnection::sessionBus();
74 QDBusMessage message = QDBusMessage::createMethodCall(
75 destination: "org.freedesktop.portal.Desktop"_L1,
76 path: "/org/freedesktop/portal/desktop"_L1,
77 interface: "org.freedesktop.portal.Settings"_L1, method: "ReadAll"_L1);
78 message << QStringList{ appearanceInterface };
79
80 QDBusPendingCall pendingCall = connection.asyncCall(message);
81 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall, this);
82 QObject::connect(
83 sender: watcher, signal: &QDBusPendingCallWatcher::finished, context: this,
84 slot: [this](QDBusPendingCallWatcher *watcher) {
85 QDBusPendingReply<QMap<QString, QVariantMap>> reply = *watcher;
86 if (reply.isValid()) {
87 QMap<QString, QVariantMap> settings = reply.value();
88 if (!settings.isEmpty()) {
89 settingChanged(group: appearanceInterface, key: colorSchemeKey,
90 value: QDBusVariant(settings.value(key: appearanceInterface).value(key: colorSchemeKey)));
91 }
92 } else {
93 qCDebug(lcQGtk3PortalInterface) << "Failed to query org.freedesktop.portal.Settings: "
94 << reply.error().message();
95 }
96 watcher->deleteLater();
97 });
98
99 QDBusConnection::sessionBus().connect(
100 service: "org.freedesktop.portal.Desktop"_L1, path: "/org/freedesktop/portal/desktop"_L1,
101 interface: "org.freedesktop.portal.Settings"_L1, name: "SettingChanged"_L1, receiver: this,
102 SLOT(settingChanged(QString, QString, QDBusVariant)));
103}
104
105void QGtk3PortalInterface::settingChanged(const QString &group, const QString &key,
106 const QDBusVariant &value)
107{
108 if (group == appearanceInterface && key == colorSchemeKey) {
109 const uint colorScheme = value.variant().toUInt();
110 // From org.freedesktop.portal.Settings.xml
111 // "1" - Prefer dark appearance
112 Qt::ColorScheme newColorScheme = colorScheme == 1 ? Qt::ColorScheme::Dark : Qt::ColorScheme::Light;
113 if (m_colorScheme != newColorScheme) {
114 m_colorScheme = newColorScheme;
115 if (m_storage)
116 m_storage->handleThemeChange();
117 }
118 }
119}
120
121QT_END_NAMESPACE
122
123#include "moc_qgtk3portalinterface_p.cpp"
124

Provided by KDAB

Privacy Policy
Start learning QML with our Intro Training
Find out more

source code of qtbase/src/plugins/platformthemes/gtk3/qgtk3portalinterface.cpp