From 0e02024084db087552a53520e829f3e4a5ae0cb4 Mon Sep 17 00:00:00 2001 From: d42 Date: Sun, 5 Jun 2022 11:51:29 +0000 Subject: [PATCH] Unread messages count as an Unity compatible badge (#1085) Co-authored-by: DeepBlueV7.X --- CMakeLists.txt | 3 ++ src/MainWindow.cpp | 3 ++ src/MainWindow.h | 2 ++ src/dock/Dock.cpp | 81 ++++++++++++++++++++++++++++++++++++++++++++++ src/dock/Dock.h | 27 ++++++++++++++++ 5 files changed, 116 insertions(+) create mode 100644 src/dock/Dock.cpp create mode 100644 src/dock/Dock.h diff --git a/CMakeLists.txt b/CMakeLists.txt index bd854cab..9444a661 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -354,6 +354,8 @@ set(SRC_FILES # Generic notification stuff src/notifications/Manager.cpp + src/dock/Dock.cpp + src/AvatarProvider.cpp src/BlurhashProvider.cpp src/Cache.cpp @@ -551,6 +553,7 @@ qt5_wrap_cpp(MOC_HEADERS src/encryption/VerificationManager.h src/notifications/Manager.h + src/dock/Dock.h src/AvatarProvider.h src/BlurhashProvider.h diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index c700294c..fb8d8ab4 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -39,6 +39,7 @@ #include "UserSettingsPage.h" #include "UsersModel.h" #include "Utils.h" +#include "dock/Dock.h" #include "emoji/EmojiModel.h" #include "emoji/Provider.h" #include "encryption/DeviceVerificationFlow.h" @@ -99,6 +100,8 @@ MainWindow::MainWindow(QWindow *parent) SLOT(iconActivated(QSystemTrayIcon::ActivationReason))); trayIcon_->setVisible(userSettings_->tray()); + dock_ = new Dock(this); + connect(chat_page_, SIGNAL(unreadMessages(int)), dock_, SLOT(setUnreadCount(int))); // load cache on event loop QTimer::singleShot(0, this, [this] { diff --git a/src/MainWindow.h b/src/MainWindow.h index 3db18a98..996d292c 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -14,6 +14,7 @@ #include #include "UserSettingsPage.h" +#include "dock/Dock.h" #include "jdenticoninterface.h" @@ -104,6 +105,7 @@ private: QSharedPointer userSettings_; //! Tray icon that shows the unread message count. TrayIcon *trayIcon_; + Dock *dock_; MxcImageProvider *imgProvider = nullptr; diff --git a/src/dock/Dock.cpp b/src/dock/Dock.cpp new file mode 100644 index 00000000..04c7507d --- /dev/null +++ b/src/dock/Dock.cpp @@ -0,0 +1,81 @@ +// SPDX-FileCopyrightText: 2022 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "dock/Dock.h" +#include +#include +#if defined(NHEKO_DBUS_SYS) +#include +Dock::Dock(QObject *parent) + : QObject(parent) + , unityServiceWatcher(new QDBusServiceWatcher(this)) +{ + unityServiceWatcher->setConnection(QDBusConnection::sessionBus()); + unityServiceWatcher->setWatchMode(QDBusServiceWatcher::WatchForUnregistration | + QDBusServiceWatcher::WatchForRegistration); + unityServiceWatcher->addWatchedService(QStringLiteral("com.canonical.Unity")); + connect(unityServiceWatcher, + &QDBusServiceWatcher::serviceRegistered, + this, + [this](const QString &service) { + Q_UNUSED(service); + unityServiceAvailable = true; + }); + connect(unityServiceWatcher, + &QDBusServiceWatcher::serviceUnregistered, + this, + [this](const QString &service) { + Q_UNUSED(service); + unityServiceAvailable = false; + }); + QDBusPendingCall listNamesCall = + QDBusConnection::sessionBus().interface()->asyncCall(QStringLiteral("ListNames")); + QDBusPendingCallWatcher *callWatcher = new QDBusPendingCallWatcher(listNamesCall, this); + connect(callWatcher, + &QDBusPendingCallWatcher::finished, + this, + [this](QDBusPendingCallWatcher *watcher) { + QDBusPendingReply reply = *watcher; + watcher->deleteLater(); + + if (reply.isError()) { + return; + } + + const QStringList &services = reply.value(); + + unityServiceAvailable = services.contains(QLatin1String("com.canonical.Unity")); + }); +} + +void +Dock::setUnreadCount(const int count) +{ + unitySetNotificationCount(count); +} +void +Dock::unitySetNotificationCount(const int count) +{ + if (unityServiceAvailable) { + const QString launcherId = qApp->desktopFileName() + QLatin1String(".desktop"); + + const QVariantMap properties{{QStringLiteral("count-visible"), count > 0}, + {QStringLiteral("count"), count}}; + + QDBusMessage message = + QDBusMessage::createSignal(QStringLiteral("/im/nheko/Nheko/UnityLauncher"), + QStringLiteral("com.canonical.Unity.LauncherEntry"), + QStringLiteral("Update")); + message.setArguments({launcherId, properties}); + QDBusConnection::sessionBus().send(message); + } +} +#else +Dock::Dock(QObject *parent) + : QObject(parent) +{} +void +Dock::setUnreadCount(const int) +{} +#endif diff --git a/src/dock/Dock.h b/src/dock/Dock.h new file mode 100644 index 00000000..a076a97c --- /dev/null +++ b/src/dock/Dock.h @@ -0,0 +1,27 @@ +// SPDX-FileCopyrightText: 2022 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once +#include +#if defined(NHEKO_DBUS_SYS) +#include +#include +#include +#endif + +class Dock : public QObject +{ + Q_OBJECT +public: + Dock(QObject *parent = nullptr); +public slots: + void setUnreadCount(const int count); + +private: +#if defined(NHEKO_DBUS_SYS) + void unitySetNotificationCount(const int count); + QDBusServiceWatcher *unityServiceWatcher = nullptr; + bool unityServiceAvailable = false; +#endif +};