1 | // Copyright (C) 2016 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 | #include <QtGui/qtgui-config.h> |
5 | |
6 | #include <QDBusMessage> |
7 | #include <QDBusInterface> |
8 | #include <QDBusServiceWatcher> |
9 | #include <QDBusConnectionInterface> |
10 | #include <QDebug> |
11 | #include <QCoreApplication> |
12 | |
13 | #ifndef QT_NO_SYSTEMTRAYICON |
14 | #include <private/qdbustrayicon_p.h> |
15 | #endif |
16 | #include <private/qdbusmenuconnection_p.h> |
17 | #include <private/qdbusmenuadaptor_p.h> |
18 | #include <private/qdbusplatformmenu_p.h> |
19 | |
20 | QT_BEGIN_NAMESPACE |
21 | |
22 | using namespace Qt::StringLiterals; |
23 | |
24 | Q_DECLARE_LOGGING_CATEGORY() |
25 | |
26 | const QString StatusNotifierWatcherService = "org.kde.StatusNotifierWatcher"_L1 ; |
27 | const QString StatusNotifierWatcherPath = "/StatusNotifierWatcher"_L1 ; |
28 | const QString StatusNotifierItemPath = "/StatusNotifierItem"_L1 ; |
29 | const QString = "/MenuBar"_L1 ; |
30 | |
31 | /*! |
32 | \class QDBusMenuConnection |
33 | \internal |
34 | A D-Bus connection which is used for both menu and tray icon services. |
35 | Connects to the session bus and registers with the respective watcher services. |
36 | */ |
37 | QDBusMenuConnection::(QObject *parent, const QString &serviceName) |
38 | : QObject(parent) |
39 | , m_serviceName(serviceName) |
40 | , m_connection(serviceName.isNull() ? QDBusConnection::sessionBus() |
41 | : QDBusConnection::connectToBus(type: QDBusConnection::SessionBus, name: serviceName)) |
42 | , m_dbusWatcher(new QDBusServiceWatcher(StatusNotifierWatcherService, m_connection, QDBusServiceWatcher::WatchForRegistration, this)) |
43 | , m_watcherRegistered(false) |
44 | { |
45 | #ifndef QT_NO_SYSTEMTRAYICON |
46 | // Start monitoring if any known tray-related services are registered. |
47 | if (m_connection.interface()->isServiceRegistered(serviceName: StatusNotifierWatcherService)) |
48 | m_watcherRegistered = true; |
49 | else |
50 | qCDebug(qLcMenu) << "failed to find service" << StatusNotifierWatcherService; |
51 | #endif |
52 | } |
53 | |
54 | QDBusMenuConnection::() |
55 | { |
56 | if (!m_serviceName.isEmpty() && m_connection.isConnected()) |
57 | QDBusConnection::disconnectFromBus(name: m_serviceName); |
58 | } |
59 | |
60 | void QDBusMenuConnection::(const QDBusError &error) |
61 | { |
62 | qWarning() << "QDBusTrayIcon encountered a D-Bus error:" << error; |
63 | } |
64 | |
65 | #ifndef QT_NO_SYSTEMTRAYICON |
66 | bool QDBusMenuConnection::(QDBusTrayIcon *item) |
67 | { |
68 | bool success = connection().registerObject(path: MenuBarPath, object: item->menu()); |
69 | if (!success) // success == false is normal, because the object may be already registered |
70 | qCDebug(qLcMenu) << "failed to register" << item->instanceId() << MenuBarPath; |
71 | return success; |
72 | } |
73 | |
74 | void QDBusMenuConnection::(QDBusTrayIcon *item) |
75 | { |
76 | if (item->menu()) |
77 | connection().unregisterObject(path: MenuBarPath); |
78 | } |
79 | |
80 | bool QDBusMenuConnection::(QDBusTrayIcon *item) |
81 | { |
82 | bool success = connection().registerObject(path: StatusNotifierItemPath, object: item); |
83 | if (!success) { |
84 | unregisterTrayIcon(item); |
85 | qWarning() << "failed to register" << item->instanceId() << StatusNotifierItemPath; |
86 | return false; |
87 | } |
88 | |
89 | if (item->menu()) |
90 | registerTrayIconMenu(item); |
91 | |
92 | return registerTrayIconWithWatcher(item); |
93 | } |
94 | |
95 | bool QDBusMenuConnection::(QDBusTrayIcon *item) |
96 | { |
97 | Q_UNUSED(item); |
98 | QDBusMessage registerMethod = QDBusMessage::createMethodCall( |
99 | destination: StatusNotifierWatcherService, path: StatusNotifierWatcherPath, interface: StatusNotifierWatcherService, |
100 | method: "RegisterStatusNotifierItem"_L1 ); |
101 | registerMethod.setArguments(QVariantList() << m_connection.baseService()); |
102 | return m_connection.callWithCallback(message: registerMethod, receiver: this, SIGNAL(trayIconRegistered()), SLOT(dbusError(QDBusError))); |
103 | } |
104 | |
105 | void QDBusMenuConnection::(QDBusTrayIcon *item) |
106 | { |
107 | unregisterTrayIconMenu(item); |
108 | connection().unregisterObject(path: StatusNotifierItemPath); |
109 | } |
110 | #endif // QT_NO_SYSTEMTRAYICON |
111 | |
112 | QT_END_NAMESPACE |
113 | |
114 | #include "moc_qdbusmenuconnection_p.cpp" |
115 | |