File indexing completed on 2024-05-05 05:38:31
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 <KWaylandExtras> 0018 #include <KWindowSystem> 0019 #include <QDebug> 0020 0021 using namespace NotificationManager; 0022 0023 Server::Server(QObject *parent) 0024 : QObject(parent) 0025 , d(new ServerPrivate(this)) 0026 { 0027 connect(d.get(), &ServerPrivate::validChanged, this, &Server::validChanged); 0028 connect(d.get(), &ServerPrivate::inhibitedChanged, this, [this] { 0029 Q_EMIT inhibitedChanged(inhibited()); 0030 }); 0031 connect(d.get(), &ServerPrivate::externalInhibitedChanged, this, [this] { 0032 Q_EMIT inhibitedByApplicationChanged(inhibitedByApplication()); 0033 }); 0034 connect(d.get(), &ServerPrivate::externalInhibitionsChanged, this, &Server::inhibitionApplicationsChanged); 0035 connect(d.get(), &ServerPrivate::serviceOwnershipLost, this, &Server::serviceOwnershipLost); 0036 } 0037 0038 Server::~Server() = default; 0039 0040 Server &Server::self() 0041 { 0042 static Server s_self; 0043 return s_self; 0044 } 0045 0046 Server *Server::create(QQmlEngine *, QJSEngine *) 0047 { 0048 QQmlEngine::setObjectOwnership(&Server::self(), QQmlEngine::CppOwnership); 0049 return &Server::self(); 0050 } 0051 0052 bool Server::init() 0053 { 0054 return d->init(); 0055 } 0056 0057 bool Server::isValid() const 0058 { 0059 return d->m_valid; 0060 } 0061 0062 ServerInfo *Server::currentOwner() const 0063 { 0064 return d->currentOwner(); 0065 } 0066 0067 void Server::closeNotification(uint notificationId, CloseReason reason) 0068 { 0069 Q_EMIT notificationRemoved(notificationId, reason); 0070 Q_EMIT d->NotificationClosed(notificationId, static_cast<uint>(reason)); // tell on DBus 0071 } 0072 0073 void Server::invokeAction(uint notificationId, 0074 const QString &actionName, 0075 const QString &xdgActivationAppId, 0076 Notifications::InvokeBehavior behavior, 0077 QWindow *window) 0078 { 0079 if (KWindowSystem::isPlatformWayland()) { 0080 const quint32 launchedSerial = KWaylandExtras::lastInputSerial(window); 0081 auto conn = std::make_shared<QMetaObject::Connection>(); 0082 *conn = connect(KWaylandExtras::self(), 0083 &KWaylandExtras::xdgActivationTokenArrived, 0084 this, 0085 [this, actionName, notificationId, launchedSerial, conn, behavior](quint32 serial, const QString &token) { 0086 if (serial == launchedSerial) { 0087 disconnect(*conn); 0088 Q_EMIT d->ActivationToken(notificationId, token); 0089 Q_EMIT d->ActionInvoked(notificationId, actionName); 0090 0091 if (behavior & Notifications::Close) { 0092 Q_EMIT d->CloseNotification(notificationId); 0093 } 0094 } 0095 }); 0096 KWaylandExtras::requestXdgActivationToken(window, launchedSerial, xdgActivationAppId); 0097 } else { 0098 KStartupInfoId startupId; 0099 startupId.initId(); 0100 0101 Q_EMIT d->ActivationToken(notificationId, QString::fromUtf8(startupId.id())); 0102 0103 Q_EMIT d->ActionInvoked(notificationId, actionName); 0104 if (behavior & Notifications::Close) { 0105 Q_EMIT d->CloseNotification(notificationId); 0106 } 0107 } 0108 } 0109 0110 void Server::reply(const QString &dbusService, uint notificationId, const QString &text, Notifications::InvokeBehavior behavior) 0111 { 0112 d->sendReplyText(dbusService, notificationId, text, behavior); 0113 } 0114 0115 uint Server::add(const Notification ¬ification) 0116 { 0117 return d->add(notification); 0118 } 0119 0120 bool Server::inhibited() const 0121 { 0122 return d->inhibited(); 0123 } 0124 0125 void Server::setInhibited(bool inhibited) 0126 { 0127 d->setInhibited(inhibited); 0128 } 0129 0130 bool Server::inhibitedByApplication() const 0131 { 0132 return d->externalInhibited(); 0133 } 0134 0135 QStringList Server::inhibitionApplications() const 0136 { 0137 QStringList applications; 0138 const auto inhibitions = d->externalInhibitions(); 0139 applications.reserve(inhibitions.count()); 0140 for (const auto &inhibition : inhibitions) { 0141 applications.append(!inhibition.applicationName.isEmpty() ? inhibition.applicationName : inhibition.desktopEntry); 0142 } 0143 return applications; 0144 } 0145 0146 QStringList Server::inhibitionReasons() const 0147 { 0148 QStringList reasons; 0149 const auto inhibitions = d->externalInhibitions(); 0150 reasons.reserve(inhibitions.count()); 0151 for (const auto &inhibition : inhibitions) { 0152 reasons.append(inhibition.reason); 0153 } 0154 return reasons; 0155 } 0156 0157 void Server::clearInhibitions() 0158 { 0159 d->clearExternalInhibitions(); 0160 } 0161 0162 #include "moc_server.cpp"