File indexing completed on 2024-04-28 16:54:37

0001 /*
0002     SPDX-FileCopyrightText: 2018 Kai Uwe Broulik <kde@privat.broulik.de>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 
0007 #include "server.h"
0008 #include "server_p.h"
0009 #include "serverinfo.h"
0010 
0011 #include "notification.h"
0012 #include "notification_p.h"
0013 
0014 #include "debug.h"
0015 
0016 #include <KStartupInfo>
0017 #include <KWindowSystem>
0018 #include <QDebug>
0019 
0020 using namespace NotificationManager;
0021 
0022 Server::Server(QObject *parent)
0023     : QObject(parent)
0024     , d(new ServerPrivate(this))
0025 {
0026     connect(d.data(), &ServerPrivate::validChanged, this, &Server::validChanged);
0027     connect(d.data(), &ServerPrivate::inhibitedChanged, this, [this] {
0028         Q_EMIT inhibitedChanged(inhibited());
0029     });
0030     connect(d.data(), &ServerPrivate::externalInhibitedChanged, this, [this] {
0031         Q_EMIT inhibitedByApplicationChanged(inhibitedByApplication());
0032     });
0033     connect(d.data(), &ServerPrivate::externalInhibitionsChanged, this, &Server::inhibitionApplicationsChanged);
0034     connect(d.data(), &ServerPrivate::serviceOwnershipLost, this, &Server::serviceOwnershipLost);
0035 }
0036 
0037 Server::~Server() = default;
0038 
0039 Server &Server::self()
0040 {
0041     static Server s_self;
0042     return s_self;
0043 }
0044 
0045 bool Server::init()
0046 {
0047     return d->init();
0048 }
0049 
0050 bool Server::isValid() const
0051 {
0052     return d->m_valid;
0053 }
0054 
0055 ServerInfo *Server::currentOwner() const
0056 {
0057     return d->currentOwner();
0058 }
0059 
0060 void Server::closeNotification(uint notificationId, CloseReason reason)
0061 {
0062     Q_EMIT notificationRemoved(notificationId, reason);
0063     Q_EMIT d->NotificationClosed(notificationId, static_cast<uint>(reason)); // tell on DBus
0064 }
0065 
0066 void Server::invokeAction(uint notificationId,
0067                           const QString &actionName,
0068                           const QString &xdgActivationAppId,
0069                           Notifications::InvokeBehavior behavior,
0070                           QWindow *window)
0071 {
0072     if (KWindowSystem::isPlatformWayland()) {
0073         const quint32 launchedSerial = KWindowSystem::lastInputSerial(window);
0074         auto conn = QSharedPointer<QMetaObject::Connection>::create();
0075         *conn = connect(KWindowSystem::self(),
0076                         &KWindowSystem::xdgActivationTokenArrived,
0077                         this,
0078                         [this, actionName, notificationId, launchedSerial, conn, behavior](quint32 serial, const QString &token) {
0079                             if (serial == launchedSerial) {
0080                                 disconnect(*conn);
0081                                 Q_EMIT d->ActivationToken(notificationId, token);
0082                                 Q_EMIT d->ActionInvoked(notificationId, actionName);
0083 
0084                                 if (behavior & Notifications::Close) {
0085                                     Q_EMIT d->CloseNotification(notificationId);
0086                                 }
0087                             }
0088                         });
0089         KWindowSystem::requestXdgActivationToken(window, launchedSerial, xdgActivationAppId);
0090     } else {
0091         KStartupInfoId startupId;
0092         startupId.initId();
0093 
0094         Q_EMIT d->ActivationToken(notificationId, QString::fromUtf8(startupId.id()));
0095 
0096         Q_EMIT d->ActionInvoked(notificationId, actionName);
0097         if (behavior & Notifications::Close) {
0098             Q_EMIT d->CloseNotification(notificationId);
0099         }
0100     }
0101 }
0102 
0103 void Server::reply(const QString &dbusService, uint notificationId, const QString &text, Notifications::InvokeBehavior behavior)
0104 {
0105     d->sendReplyText(dbusService, notificationId, text, behavior);
0106 }
0107 
0108 uint Server::add(const Notification &notification)
0109 {
0110     return d->add(notification);
0111 }
0112 
0113 bool Server::inhibited() const
0114 {
0115     return d->inhibited();
0116 }
0117 
0118 void Server::setInhibited(bool inhibited)
0119 {
0120     d->setInhibited(inhibited);
0121 }
0122 
0123 bool Server::inhibitedByApplication() const
0124 {
0125     return d->externalInhibited();
0126 }
0127 
0128 QStringList Server::inhibitionApplications() const
0129 {
0130     QStringList applications;
0131     const auto inhibitions = d->externalInhibitions();
0132     applications.reserve(inhibitions.count());
0133     for (const auto &inhibition : inhibitions) {
0134         applications.append(!inhibition.applicationName.isEmpty() ? inhibition.applicationName : inhibition.desktopEntry);
0135     }
0136     return applications;
0137 }
0138 
0139 QStringList Server::inhibitionReasons() const
0140 {
0141     QStringList reasons;
0142     const auto inhibitions = d->externalInhibitions();
0143     reasons.reserve(inhibitions.count());
0144     for (const auto &inhibition : inhibitions) {
0145         reasons.append(inhibition.reason);
0146     }
0147     return reasons;
0148 }
0149 
0150 void Server::clearInhibitions()
0151 {
0152     d->clearExternalInhibitions();
0153 }
0154 
0155 #include "moc_server.cpp"