Connect to the notifications interface once it becomes available

Currently does not work and not fix #693, because the signal isn't
actually emitted, if the service is already available...
This commit is contained in:
Nicolas Werner 2023-06-09 00:37:02 +02:00
parent 8259891a42
commit 81305c3aef
No known key found for this signature in database
GPG key ID: C8D75E610773F2D9
2 changed files with 55 additions and 42 deletions

View file

@ -14,6 +14,7 @@
#if defined(NHEKO_DBUS_SYS) #if defined(NHEKO_DBUS_SYS)
#include <QtDBus/QDBusArgument> #include <QtDBus/QDBusArgument>
#include <QtDBus/QDBusInterface> #include <QtDBus/QDBusInterface>
#include <QtDBus/QDBusServiceWatcher>
#endif #endif
struct roomEventId struct roomEventId
@ -58,7 +59,8 @@ public:
#endif #endif
private: private:
QDBusInterface dbus; std::optional<QDBusInterface> dbus;
QDBusServiceWatcher watcher;
void systemPostNotification(const QString &room_id, void systemPostNotification(const QString &room_id,
const QString &event_id, const QString &event_id,
@ -67,8 +69,8 @@ private:
const QImage &icon); const QImage &icon);
void closeNotification(uint id); void closeNotification(uint id);
const bool hasMarkup_; bool hasMarkup_ = false;
const bool hasImages_; bool hasImages_ = false;
#endif #endif
#if defined(Q_OS_MACOS) #if defined(Q_OS_MACOS)

View file

@ -22,6 +22,7 @@
#include "Cache.h" #include "Cache.h"
#include "EventAccessors.h" #include "EventAccessors.h"
#include "Logging.h"
#include "MxcImageProvider.h" #include "MxcImageProvider.h"
#include "UserSettingsPage.h" #include "UserSettingsPage.h"
#include "Utils.h" #include "Utils.h"
@ -29,47 +30,45 @@
NotificationsManager::NotificationsManager(QObject *parent) NotificationsManager::NotificationsManager(QObject *parent)
: QObject(parent) : QObject(parent)
, dbus(QStringLiteral("org.freedesktop.Notifications"), , watcher(this)
QStringLiteral("/org/freedesktop/Notifications"),
QStringLiteral("org.freedesktop.Notifications"),
QDBusConnection::sessionBus(),
this)
, hasMarkup_{std::invoke([this]() -> bool {
auto caps = dbus.call("GetCapabilities").arguments();
for (const auto &x : qAsConst(caps))
if (x.toStringList().contains("body-markup"))
return true;
return false;
})}
, hasImages_{std::invoke([this]() -> bool {
auto caps = dbus.call("GetCapabilities").arguments();
for (const auto &x : qAsConst(caps))
if (x.toStringList().contains("body-images"))
return true;
return false;
})}
{ {
qDBusRegisterMetaType<QImage>(); qDBusRegisterMetaType<QImage>();
connect(&watcher, &QDBusServiceWatcher::serviceRegistered, this, [this](QString) {
dbus.emplace(QStringLiteral("org.freedesktop.Notifications"),
QStringLiteral("/org/freedesktop/Notifications"),
QStringLiteral("org.freedesktop.Notifications"),
QDBusConnection::sessionBus(),
this);
connect(
&*dbus, SIGNAL(ActionInvoked(uint, QString)), this, SLOT(actionInvoked(uint, QString)));
connect(&*dbus,
SIGNAL(NotificationClosed(uint, uint)),
this,
SLOT(notificationClosed(uint, uint)));
connect(&*dbus,
SIGNAL(NotificationReplied(uint, QString)),
this,
SLOT(notificationReplied(uint, QString)));
hasMarkup_ = false;
hasImages_ = false;
auto caps = dbus->call("GetCapabilities").arguments();
for (const auto &x : qAsConst(caps)) {
if (x.toStringList().contains("body-markup"))
hasMarkup_ = true;
if (x.toStringList().contains("body-images"))
hasImages_ = true;
}
});
watcher.setWatchMode(QDBusServiceWatcher::WatchForRegistration);
watcher.setConnection(QDBusConnection::sessionBus());
watcher.addWatchedService(QStringLiteral("org.freedesktop.Notifications"));
// clang-format off // clang-format off
QDBusConnection::sessionBus().connect(QStringLiteral("org.freedesktop.Notifications"),
QStringLiteral("/org/freedesktop/Notifications"),
QStringLiteral("org.freedesktop.Notifications"),
QStringLiteral("ActionInvoked"),
this,
SLOT(actionInvoked(uint,QString)));
QDBusConnection::sessionBus().connect(QStringLiteral("org.freedesktop.Notifications"),
QStringLiteral("/org/freedesktop/Notifications"),
QStringLiteral("org.freedesktop.Notifications"),
QStringLiteral("NotificationClosed"),
this,
SLOT(notificationClosed(uint,uint)));
QDBusConnection::sessionBus().connect(QStringLiteral("org.freedesktop.Notifications"),
QStringLiteral("/org/freedesktop/Notifications"),
QStringLiteral("org.freedesktop.Notifications"),
QStringLiteral("NotificationReplied"),
this,
SLOT(notificationReplied(uint,QString)));
// clang-format on // clang-format on
connect(this, connect(this,
@ -155,6 +154,12 @@ NotificationsManager::systemPostNotification(const QString &room_id,
const QString &text, const QString &text,
const QImage &icon) const QImage &icon)
{ {
if (!dbus) {
nhlog::ui()->warn(
"Dropping notification because we could not connect to the dbus interface.");
return;
}
QVariantMap hints; QVariantMap hints;
hints[QStringLiteral("image-data")] = icon; hints[QStringLiteral("image-data")] = icon;
hints[QStringLiteral("sound-name")] = "message-new-instant"; hints[QStringLiteral("sound-name")] = "message-new-instant";
@ -196,7 +201,7 @@ NotificationsManager::systemPostNotification(const QString &room_id,
argumentList << hints; // hints argumentList << hints; // hints
argumentList << (int)-1; // timeout in ms argumentList << (int)-1; // timeout in ms
QDBusPendingCall call = dbus.asyncCallWithArgumentList(QStringLiteral("Notify"), argumentList); QDBusPendingCall call = dbus->asyncCallWithArgumentList(QStringLiteral("Notify"), argumentList);
auto watcher = new QDBusPendingCallWatcher{call, this}; auto watcher = new QDBusPendingCallWatcher{call, this};
connect( connect(
watcher, &QDBusPendingCallWatcher::finished, this, [watcher, this, room_id, event_id]() { watcher, &QDBusPendingCallWatcher::finished, this, [watcher, this, room_id, event_id]() {
@ -212,7 +217,13 @@ NotificationsManager::systemPostNotification(const QString &room_id,
void void
NotificationsManager::closeNotification(uint id) NotificationsManager::closeNotification(uint id)
{ {
auto call = dbus.asyncCall(QStringLiteral("CloseNotification"), (uint)id); // replace_id if (!dbus) {
nhlog::ui()->warn(
"Not removing notification because we could not connect to the dbus interface.");
return;
}
auto call = dbus->asyncCall(QStringLiteral("CloseNotification"), (uint)id); // replace_id
auto watcher = new QDBusPendingCallWatcher{call, this}; auto watcher = new QDBusPendingCallWatcher{call, this};
connect(watcher, &QDBusPendingCallWatcher::finished, this, [watcher]() { connect(watcher, &QDBusPendingCallWatcher::finished, this, [watcher]() {
if (watcher->reply().type() == QDBusMessage::ErrorMessage) { if (watcher->reply().type() == QDBusMessage::ErrorMessage) {