2 #include "notificationsinterface.h" 4 #include <QCoreApplication> 5 #include <QDBusConnection> 6 #include <QDBusPendingReply> 37 static std::map<uint, DBusNotification *> pendingNotifications;
39 OrgFreedesktopNotificationsInterface *DBusNotification::s_dbusInterface =
nullptr;
49 inline SwappedImage::SwappedImage(
const QImage &image)
50 : QImage(image.rgbSwapped())
81 argument.beginStructure();
83 argument.endStructure();
89 argument.beginStructure();
91 argument.endStructure();
106 : width(image.width())
107 , height(image.height())
108 , rowstride(image.bytesPerLine())
109 , hasAlpha(image.hasAlphaChannel())
110 , channels(image.isGrayscale() ? 1 : hasAlpha ? 4 : 3)
111 , bitsPerSample(image.depth() / channels)
112 , data(reinterpret_cast<const char *>(image.bits()), image.byteCount())
113 , isValid(!image.isNull())
124 return isValid ? QImage(reinterpret_cast<const uchar *>(
data.constData()),
width,
height,
hasAlpha ? QImage::Format_ARGB32 : QImage::Format_RGB32)
131 return QVariant::fromValue(*
this);
176 void DBusNotification::initInterface()
178 if (!s_dbusInterface) {
179 qDBusRegisterMetaType<NotificationImage>();
180 s_dbusInterface =
new OrgFreedesktopNotificationsInterface(
181 QStringLiteral(
"org.freedesktop.Notifications"), QStringLiteral(
"/org/freedesktop/Notifications"), QDBusConnection::sessionBus());
183 connect(s_dbusInterface, &OrgFreedesktopNotificationsInterface::NotificationClosed, &DBusNotification::handleNotificationClosed);
192 auto i = pendingNotifications.find(m_id);
193 if (i != pendingNotifications.end()) {
194 pendingNotifications.erase(i);
205 return s_dbusInterface->isValid();
215 m_icon = QStringLiteral(
"dialog-information");
218 m_icon = QStringLiteral(
"dialog-warning");
221 m_icon = QStringLiteral(
"dialog-critical");
266 if (!s_dbusInterface->isValid()) {
272 m_watcher =
new QDBusPendingCallWatcher(
273 s_dbusInterface->Notify(QCoreApplication::applicationName(), m_id, m_icon, m_title, m_msg, m_actions, m_hints, m_timeout),
this);
274 connect(m_watcher, &QDBusPendingCallWatcher::finished,
this, &DBusNotification::handleNotifyResult);
308 if (!m_msg.startsWith(QStringLiteral(
"•"))) {
309 m_msg.insert(0, QStringLiteral(
"• "));
311 m_msg.append(QStringLiteral(
"\n• "));
321 if (!s_dbusInterface->isValid()) {
326 const auto *
const watcher =
new QDBusPendingCallWatcher(s_dbusInterface->GetCapabilities());
327 connect(watcher, &QDBusPendingCallWatcher::finished, [&callback](QDBusPendingCallWatcher *watcher) {
328 watcher->deleteLater();
329 const QDBusPendingReply<QStringList> returnValue(*watcher);
330 if (returnValue.isError()) {
348 s_dbusInterface->CloseNotification(m_id);
355 void DBusNotification::handleNotifyResult(QDBusPendingCallWatcher *watcher)
357 if (watcher != m_watcher) {
361 watcher->deleteLater();
364 QDBusPendingReply<uint> returnValue = *watcher;
365 if (returnValue.isError()) {
369 pendingNotifications[m_id = returnValue.argumentAt<0>()] =
this;
377 void DBusNotification::handleNotificationClosed(uint
id, uint reason)
379 auto i = pendingNotifications.find(
id);
380 if (i != pendingNotifications.end()) {
382 notification->m_id = 0;
384 pendingNotifications.erase(i);
391 void DBusNotification::handleActionInvoked(uint
id,
const QString &action)
393 auto i = pendingNotifications.find(
id);
394 if (i != pendingNotifications.end()) {
396 emit notification->actionInvoked(action);
401 notification->m_id = 0;
402 pendingNotifications.erase(i);
405 s_dbusInterface->CloseNotification(i->first);
void setIcon(const QString &icon)
Sets the icon name.
static NotificationImage fromDBusArgument(const QVariant &variant)
void closed(NotificationCloseReason reason)
Emitted when the notification has been closed.
bool update(const QString &line)
Updates the message and shows/updates the notification.
const QImage image() const
Returns the image.
void hide()
Hides the notification (if still visible).
QVariant hint(const QString &name) const
Returns the hint with the specified name.
Q_DECLARE_METATYPE(MiscUtils::NotificationImage)
static bool queryCapabilities(const std::function< void(Capabilities &&capabilities)> &callback)
void shown()
Emitted when the notification could be shown successful.
static bool isAvailable()
Returns whether the notification D-Bus daemon is running.
QDBusArgument & operator<<(QDBusArgument &argument, const NotificationImage &img)
void setImage(const QImage &image)
Sets the image.
QVariant toDBusArgument() const
bool isVisible() const
Returns whether the notification is (still) visible.
DBusNotification(const QString &title, NotificationIcon icon=NotificationIcon::Information, int timeout=10000, QObject *parent=nullptr)
Creates a new notification (which is not shown instantly).
bool show()
Shows the notification.
void error()
Emitted when the notification couldn't be shown.
const QDBusArgument & operator>>(const QDBusArgument &argument, NotificationImage &img)
~DBusNotification()
Closes the notification if still shown and delete the object.
The SwappedImage struct represents RGB-interved version of the image specified on construction...
void deleteOnCloseOrError()
Makes the notification object delete itself when the notification has been closed or an error occured...
The NotificationImage struct is a raw data image format.
const QString & icon() const
const QString & message() const