File indexing completed on 2024-12-08 10:25:56

0001 /*
0002    SPDX-FileCopyrightText: 2018-2024 Laurent Montel <montel@kde.org>
0003 
0004    SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "unityservicemanager.h"
0008 #include "ruqola_debug.h"
0009 #include <QApplication>
0010 #include <QDBusConnection>
0011 #include <QDBusConnectionInterface>
0012 #include <QDBusMessage>
0013 #include <QDBusPendingCallWatcher>
0014 #include <QDBusPendingReply>
0015 #include <QDBusServiceWatcher>
0016 
0017 UnityServiceManager::UnityServiceManager(QObject *parent)
0018     : QObject(parent)
0019     , mUnityServiceWatcher(new QDBusServiceWatcher(this))
0020 {
0021     initUnity();
0022 }
0023 
0024 UnityServiceManager::~UnityServiceManager() = default;
0025 
0026 void UnityServiceManager::updateCount()
0027 {
0028     if (mUnityServiceAvailable) {
0029         const QString launcherId = qApp->desktopFileName() + QLatin1String(".desktop");
0030 
0031         const QVariantMap properties{{QStringLiteral("count-visible"), mCount > 0}, {QStringLiteral("count"), mCount}};
0032 
0033         QDBusMessage message = QDBusMessage::createSignal(QStringLiteral("/org/ruqola/UnityLauncher"),
0034                                                           QStringLiteral("com.canonical.Unity.LauncherEntry"),
0035                                                           QStringLiteral("Update"));
0036         message.setArguments({launcherId, properties});
0037         QDBusConnection::sessionBus().send(message);
0038     }
0039 }
0040 
0041 void UnityServiceManager::setCount(int count)
0042 {
0043     if (mCount != count) {
0044         mCount = count;
0045         updateCount();
0046     }
0047 }
0048 
0049 void UnityServiceManager::initUnity()
0050 {
0051     mUnityServiceWatcher->setConnection(QDBusConnection::sessionBus());
0052     mUnityServiceWatcher->setWatchMode(QDBusServiceWatcher::WatchForUnregistration | QDBusServiceWatcher::WatchForRegistration);
0053     mUnityServiceWatcher->addWatchedService(QStringLiteral("com.canonical.Unity"));
0054     connect(mUnityServiceWatcher, &QDBusServiceWatcher::serviceRegistered, this, [this](const QString &service) {
0055         Q_UNUSED(service)
0056         mUnityServiceAvailable = true;
0057         updateCount();
0058     });
0059 
0060     connect(mUnityServiceWatcher, &QDBusServiceWatcher::serviceUnregistered, this, [this](const QString &service) {
0061         Q_UNUSED(service)
0062         mUnityServiceAvailable = false;
0063     });
0064 
0065     // QDBusConnectionInterface::isServiceRegistered blocks
0066     QDBusPendingCall listNamesCall = QDBusConnection::sessionBus().interface()->asyncCall(QStringLiteral("ListNames"));
0067     auto callWatcher = new QDBusPendingCallWatcher(listNamesCall, this);
0068     connect(callWatcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *watcher) {
0069         QDBusPendingReply<QStringList> reply = *watcher;
0070         watcher->deleteLater();
0071 
0072         if (reply.isError()) {
0073             qCWarning(RUQOLA_LOG) << " reply" << reply.error().message();
0074         }
0075 
0076         const QStringList &services = reply.value();
0077 
0078         mUnityServiceAvailable = services.contains(QLatin1String("com.canonical.Unity"));
0079         if (mUnityServiceAvailable) {
0080             updateCount();
0081         }
0082     });
0083 }
0084 
0085 #include "moc_unityservicemanager.cpp"