// // Created by zpf on 23-2-2. // #include "notification-client.h" #include "notification-client-private.h" #include #include "notificationclientadaptor.h" using namespace UkuiNotification; NotificationClientPrivate::NotificationClientPrivate(NotificationClient *q, QObject *parent) : QObject(parent), q(q) { } NotificationClientPrivate::~NotificationClientPrivate() { if(m_notificationsInterface) { m_notificationsInterface->call(QDBus::NoBlock, QStringLiteral("UnRegisterClient")); delete m_notificationsInterface; m_notificationsInterface = nullptr; } } bool NotificationClientPrivate::init() { new NotificationClientAdaptor(this); QDBusConnection conn = QDBusConnection::sessionBus(); if(!conn.registerObject(clientServicePath(), clientServiceInterface(), this)) { qWarning() << "Failed to register NotificationClient DBus object!" << conn.lastError(); return false; } QDBusServiceWatcher *watcher = new QDBusServiceWatcher(QStringLiteral("org.freedesktop.Notifications"), conn, QDBusServiceWatcher::WatchForOwnerChange, this); connect(watcher, &QDBusServiceWatcher::serviceOwnerChanged, this, [](const QString &service, const QString &oldOwner, const QString &newOwner){ qDebug() << "serviceOwnerChanged" << service << oldOwner << newOwner; }); return registerClient(); } bool NotificationClientPrivate::registerClient() { QDBusConnection conn = QDBusConnection::sessionBus(); m_notificationsInterface = new OrgFreedesktopNotificationsInterface(QStringLiteral("org.freedesktop.Notifications"), QStringLiteral("/org/freedesktop/Notifications"), conn); if(!m_notificationsInterface->isValid()) { qWarning() << "Failed to creat dbus interface for notification server!" << conn.lastError(); return false; } connect(m_notificationsInterface, &OrgFreedesktopNotificationsInterface::NotificationClosed, this, &NotificationClientPrivate::notificationClosed); if(!m_serverInterface) { m_serverInterface = new QDBusInterface(QStringLiteral("org.freedesktop.Notifications"), QStringLiteral("/org/freedesktop/Notifications"), QStringLiteral("org.ukui.NotificationServer"), conn, this); if(!m_serverInterface->isValid()) { qWarning() << "Failed to create notification server interface! " << conn.lastError(); return false; } } QDBusMessage reply = m_serverInterface->call(QStringLiteral("RegisterClient")); if (reply.type() == QDBusMessage::ErrorMessage || reply.type() == QDBusMessage::InvalidMessage) { qWarning() << "Failed to call RegisterClient!" << conn.lastError() << reply.type(); return false; } return true; } void NotificationClientPrivate::unRegisterClient() { disconnect(m_notificationsInterface, &OrgFreedesktopNotificationsInterface::NotificationClosed, this, &NotificationClientPrivate::notificationClosed); if(m_notificationsInterface) { delete m_notificationsInterface; m_notificationsInterface = nullptr; } } QString NotificationClientPrivate::clientServicePath() { return QStringLiteral("/NotificationClient"); } QString NotificationClientPrivate::clientServiceInterface() { return QStringLiteral("org.ukui.NotificationClient"); } void NotificationClientPrivate::Notify(const QString &app_name, uint replaces_id, const QString &app_icon, const QString &summary, const QString &body, const QStringList &actions, const QVariantMap &hints, int timeout) { PopupNotification notification(replaces_id); notification.setSummary(summary); notification.setBody(body); notification.setApplicationName(app_name); notification.setAplicationIconName(app_icon); notification.setActions(actions); notification.setTimeout(timeout); notification.setHints(hints); Q_EMIT q->newNotification(notification); } void NotificationClientPrivate::notificationClosed(uint id, uint reason) { NotificationClient::CloseReason closeReason = NotificationClient::Undefined; switch (reason) { case 1: closeReason = NotificationClient::Expired; break; case 2: closeReason = NotificationClient::DismissedByUser; break; case 3: closeReason = NotificationClient::Revoked; break; } Q_EMIT q->notificationClosed(id, closeReason); } void NotificationClientPrivate::closeNotification(uint id, NotificationClient::CloseReason reason) { if(!m_notificationsInterface) { return; } QDBusMessage reply = m_notificationsInterface->callWithArgumentList(QDBus::NoBlock, QStringLiteral("CloseNotification"), {id, reason}); if (reply.type() == QDBusMessage::ErrorMessage) { qWarning() << "Failed to call CloseNotification!" << QDBusConnection::sessionBus().lastError(); } } void NotificationClientPrivate::serviceChange(const QString &service, const QString &oldOwner, const QString &newOwner) { qDebug() << "Notification Service" << service << "status change, old owner:" << oldOwner << "new:" << newOwner; if(newOwner.isEmpty()) { unRegisterClient(); } else if (oldOwner.isEmpty()) { registerClient(); } } NotificationClient::NotificationClient(QObject *parent) : QObject(parent), d(new NotificationClientPrivate(this)) { qRegisterMetaType("PopupNotification"); } NotificationClient::~NotificationClient() = default; bool NotificationClient::registerClient() { return d->init(); } void NotificationClient::closeNotification(uint id, NotificationClient::CloseReason reason) { d->closeNotification(id, reason); }