File indexing completed on 2024-05-05 17:45:18

0001 /*
0002     SPDX-FileCopyrightText: 2009 Marco Martin <notmart@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "statusnotifierwatcher.h"
0008 
0009 #include <QDBusConnection>
0010 #include <QDBusServiceWatcher>
0011 #include <QDebug>
0012 
0013 #include <kpluginfactory.h>
0014 
0015 #include "statusnotifieritem_interface.h"
0016 #include "statusnotifierwatcheradaptor.h"
0017 
0018 K_PLUGIN_CLASS_WITH_JSON(StatusNotifierWatcher, "statusnotifierwatcher.json")
0019 
0020 StatusNotifierWatcher::StatusNotifierWatcher(QObject *parent, const QList<QVariant> &)
0021     : KDEDModule(parent)
0022 {
0023     setModuleName(QStringLiteral("StatusNotifierWatcher"));
0024     new StatusNotifierWatcherAdaptor(this);
0025     QDBusConnection dbus = QDBusConnection::sessionBus();
0026     dbus.registerObject(QStringLiteral("/StatusNotifierWatcher"), this);
0027     dbus.registerService(QStringLiteral("org.kde.StatusNotifierWatcher"));
0028 
0029     m_serviceWatcher = new QDBusServiceWatcher(this);
0030     m_serviceWatcher->setConnection(dbus);
0031     m_serviceWatcher->setWatchMode(QDBusServiceWatcher::WatchForUnregistration);
0032 
0033     connect(m_serviceWatcher, &QDBusServiceWatcher::serviceUnregistered, this, &StatusNotifierWatcher::serviceUnregistered);
0034 }
0035 
0036 StatusNotifierWatcher::~StatusNotifierWatcher()
0037 {
0038     QDBusConnection dbus = QDBusConnection::sessionBus();
0039     dbus.unregisterService(QStringLiteral("org.kde.StatusNotifierWatcher"));
0040 }
0041 
0042 void StatusNotifierWatcher::RegisterStatusNotifierItem(const QString &serviceOrPath)
0043 {
0044     QString service;
0045     QString path;
0046     if (serviceOrPath.startsWith(QLatin1Char('/'))) {
0047         service = message().service();
0048         path = serviceOrPath;
0049     } else {
0050         service = serviceOrPath;
0051         path = QStringLiteral("/StatusNotifierItem");
0052     }
0053     QString notifierItemId = service + path;
0054     if (m_registeredServices.contains(notifierItemId)) {
0055         return;
0056     }
0057     m_serviceWatcher->addWatchedService(service);
0058     if (QDBusConnection::sessionBus().interface()->isServiceRegistered(service).value()) {
0059         // check if the service has registered a SystemTray object
0060         org::kde::StatusNotifierItem trayclient(service, path, QDBusConnection::sessionBus());
0061         if (trayclient.isValid()) {
0062             qDebug() << "Registering" << notifierItemId << "to system tray";
0063             m_registeredServices.append(notifierItemId);
0064             Q_EMIT StatusNotifierItemRegistered(notifierItemId);
0065         } else {
0066             m_serviceWatcher->removeWatchedService(service);
0067         }
0068     } else {
0069         m_serviceWatcher->removeWatchedService(service);
0070     }
0071 }
0072 
0073 QStringList StatusNotifierWatcher::RegisteredStatusNotifierItems() const
0074 {
0075     return m_registeredServices;
0076 }
0077 
0078 void StatusNotifierWatcher::serviceUnregistered(const QString &name)
0079 {
0080     qDebug() << "Service " << name << "unregistered";
0081     m_serviceWatcher->removeWatchedService(name);
0082 
0083     const QString match = name + QLatin1Char('/');
0084     QStringList::Iterator it = m_registeredServices.begin();
0085     while (it != m_registeredServices.end()) {
0086         if (it->startsWith(match)) {
0087             QString name = *it;
0088             it = m_registeredServices.erase(it);
0089             Q_EMIT StatusNotifierItemUnregistered(name);
0090         } else {
0091             ++it;
0092         }
0093     }
0094 }
0095 
0096 void StatusNotifierWatcher::RegisterStatusNotifierHost(const QString &service)
0097 {
0098 }
0099 
0100 bool StatusNotifierWatcher::IsStatusNotifierHostRegistered() const
0101 {
0102     return true;
0103 }
0104 
0105 int StatusNotifierWatcher::ProtocolVersion() const
0106 {
0107     return 0;
0108 }
0109 
0110 #include "statusnotifierwatcher.moc"