File indexing completed on 2025-01-12 04:20:11
0001 #include "freedesktopnotification_backend.h" 0002 0003 #include "libsnore/notification/notification.h" 0004 #include "libsnore/notification/notification_p.h" 0005 #include "libsnore/snore.h" 0006 #include "libsnore/snore_p.h" 0007 #include "libsnore/utils.h" 0008 0009 #include "fredesktopnotification.h" 0010 0011 SnorePlugin::Freedesktop::Freedesktop() 0012 { 0013 m_interface = new org::freedesktop::Notifications(QStringLiteral("org.freedesktop.Notifications"), 0014 QStringLiteral("/org/freedesktop/Notifications"), 0015 QDBusConnection::sessionBus(), this); 0016 QDBusPendingReply<QStringList> reply = m_interface->GetCapabilities(); 0017 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); 0018 connect(watcher, &QDBusPendingCallWatcher::finished, [reply, watcher, this]() { 0019 m_supportsRichtext = reply.value().contains(QStringLiteral("body-markup")); 0020 watcher->deleteLater(); 0021 }); 0022 connect(this, &Freedesktop::enabledChanged, [this](bool enabled) { 0023 if (enabled) { 0024 connect(m_interface, &org::freedesktop::Notifications::ActionInvoked, this, &Freedesktop::slotActionInvoked); 0025 connect(m_interface, &org::freedesktop::Notifications::NotificationClosed, this , &Freedesktop::slotNotificationClosed); 0026 } else { 0027 disconnect(m_interface, &org::freedesktop::Notifications::ActionInvoked, this, &Freedesktop::slotActionInvoked); 0028 disconnect(m_interface, &org::freedesktop::Notifications::NotificationClosed, this , &Freedesktop::slotNotificationClosed); 0029 0030 } 0031 }); 0032 } 0033 0034 bool SnorePlugin::Freedesktop::canCloseNotification() const 0035 { 0036 return true; 0037 } 0038 0039 bool SnorePlugin::Freedesktop::canUpdateNotification() const 0040 { 0041 return true; 0042 } 0043 0044 void SnorePlugin::Freedesktop::slotNotify(Snore::Notification noti) 0045 { 0046 if (noti.data()->sourceAndTargetAreSimilar(this)) { 0047 return; 0048 } 0049 0050 QStringList actions; 0051 foreach(int k, noti.actions().keys()) { 0052 actions << QString::number(k) << noti.actions()[k].name(); 0053 } 0054 QVariantMap hints; 0055 0056 FreedesktopImageHint image(noti.icon().pixmap(QSize(128, 128)).toImage()); 0057 hints.insert(QStringLiteral("image_data"), QVariant::fromValue(image)); 0058 0059 char urgency = 1; 0060 if (noti.priority() < 0) { 0061 urgency = 0; 0062 } else if (noti.priority() > 2) { 0063 urgency = 2; 0064 } 0065 hints.insert(QStringLiteral("urgency"), urgency); 0066 0067 if (noti.application().constHints().contains("desktop-entry")) { 0068 hints.insert(QStringLiteral("desktop-entry"), noti.application().constHints().value("desktop-entry")); 0069 } 0070 0071 hints.insert(QStringLiteral("suppress-sound"), noti.constHints().value("silent").toBool()); 0072 0073 uint updateId = 0; 0074 if (noti.isUpdate()) { 0075 updateId = noti.old().hints().privateValue(this, "id").toUInt(); 0076 m_dbusIdMap.take(updateId); 0077 } 0078 0079 QString title = noti.application().name() + QLatin1String(" - ") + noti.title(m_supportsRichtext ? Snore::Utils::AllMarkup : Snore::Utils::NoMarkup); 0080 QString body(noti.text(m_supportsRichtext ? Snore::Utils::AllMarkup : Snore::Utils::NoMarkup)); 0081 //TODO: add app icon hint? 0082 QDBusPendingReply<uint> id = m_interface->Notify(noti.application().name(), updateId, QString(), title, 0083 body, actions, hints, noti.isSticky() ? -1 : noti.timeout() * 1000); 0084 0085 id.waitForFinished(); 0086 noti.hints().setPrivateValue(this, "id", id.value()); 0087 m_dbusIdMap[id.value()] = noti; 0088 slotNotificationDisplayed(noti); 0089 0090 qCDebug(SNORE) << noti.id() << "|" << id.value(); 0091 } 0092 0093 void SnorePlugin::Freedesktop::slotActionInvoked(const uint id, const QString &actionID) 0094 { 0095 qCDebug(SNORE) << id << m_dbusIdMap[id]; 0096 Snore::Notification noti = m_dbusIdMap[id]; 0097 if (!noti.isValid()) { 0098 return; 0099 } 0100 slotNotificationActionInvoked(noti, noti.actions().value(actionID.toInt()));; 0101 } 0102 0103 void SnorePlugin::Freedesktop::slotCloseNotification(Snore::Notification notification) 0104 { 0105 uint id = notification.hints().privateValue(this, "id").toUInt(); 0106 qCDebug(SNORE) << notification.id() << id; 0107 m_interface->CloseNotification(id); 0108 } 0109 0110 void SnorePlugin::Freedesktop::slotNotificationClosed(const uint id, const uint reason) 0111 { 0112 /* 0113 * 0114 * The reason the notification was closed. 0115 * 0116 * 1 - The notification expired. 0117 * 0118 * 2 - The notification was dismissed by the user. 0119 * 0120 * 3 - The notification was closed by a call to CloseNotification. 0121 * 0122 * 4 - Undefined/reserved reasons. 0123 */ 0124 Snore::Notification::CloseReasons closeReason; 0125 switch (reason) { 0126 case (1): 0127 closeReason = Snore::Notification::TimedOut; 0128 break; 0129 case (2): 0130 closeReason = Snore::Notification::Dismissed; 0131 break; 0132 case (3): 0133 closeReason = Snore::Notification::Closed; 0134 break; 0135 default: 0136 closeReason = Snore::Notification::None; 0137 } 0138 0139 qCDebug(SNORE) << id << "|" << closeReason << reason; 0140 if (id == 0) { 0141 return; 0142 } 0143 Snore::Notification noti = m_dbusIdMap.take(id); 0144 if (noti.isValid()) { 0145 closeNotification(noti, closeReason); 0146 } 0147 } 0148