From 66e2c01029efad7f6195cebcf96175152ce2ce22 Mon Sep 17 00:00:00 2001 From: sudden6 Date: Wed, 11 Jul 2018 20:55:16 +0200 Subject: [PATCH] feat(notify): add desktop notifications using snorenotify This commit adds very basic support for desktop notifications on friend request, group invites, friend messages and group messages. --- CMakeLists.txt | 12 +++ INSTALL.md | 12 +++ cmake/Dependencies.cmake | 6 ++ .../desktop_notifications/desktopnotify.cpp | 81 +++++++++++++++++++ .../desktop_notifications/desktopnotify.h | 37 +++++++++ src/widget/widget.cpp | 12 +++ src/widget/widget.h | 9 ++- 7 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 src/platform/desktop_notifications/desktopnotify.cpp create mode 100644 src/platform/desktop_notifications/desktopnotify.h diff --git a/CMakeLists.txt b/CMakeLists.txt index ca54c1e79..4e883ab6b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,7 @@ option(USE_CCACHE "Use ccache when available" ON) option(SPELL_CHECK "Enable spell cheching support" ON) option(SVGZ_ICON "Compress the SVG icon of qTox" ON) option(ASAN "Compile with AddressSanitizer" OFF) +option(DESKTOP_NOTIFICATIONS "Use snorenotify for desktop notifications" OFF) # process generated files if cmake >= 3.10 if(POLICY CMP0071) @@ -650,6 +651,17 @@ else() message(STATUS "NOT using update check") endif() +if (${DESKTOP_NOTIFICATIONS}) + add_definitions(-DDESKTOP_NOTIFICATIONS=1) + set(${PROJECT_NAME}_SOURCES ${${PROJECT_NAME}_SOURCES} + src/platform/desktop_notifications/desktopnotify.cpp + src/platform/desktop_notifications/desktopnotify.h) + message(STATUS "using desktop notifications") +else() + add_definitions(-DDESKTOP_NOTIFICATIONS=0) + message(STATUS "not using desktop notifications") +endif() + if (MINGW) STRING(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWER) if (CMAKE_BUILD_TYPE_LOWER MATCHES debug) diff --git a/INSTALL.md b/INSTALL.md index 5dd8ddb40..9f1d87ed9 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -46,6 +46,7 @@ | [sqlcipher] | >= 3.2.0 | | | [pkg-config] | >= 0.28 | | | [filteraudio] | >= 0.0.1 | optional dependency | +| [snorenotify] | >= 0.7.0 | optional dependency | ## Optional dependencies @@ -116,6 +117,16 @@ Disabled by default. To enable: `-DENABLE_APPINDICATOR=True` +#### Snorenotify desktop notification backend + +Disabled by default + +| Name | Version | +|-------------------|-----------| +| [snorenotify] | >= 0.7.0 | + +To enable: `-DDESKTOP_NOTIFICATIONS=True` + ## Linux ### Simple install @@ -829,3 +840,4 @@ Switches: [toxcore]: https://github.com/TokTok/c-toxcore/ [filteraudio]: https://github.com/irungentoo/filter_audio [sonnet]: https://github.com/KDE/sonnet +[snorenotify]: https://techbase.kde.org/Projects/Snorenotify diff --git a/cmake/Dependencies.cmake b/cmake/Dependencies.cmake index 544916202..1d402bf35 100644 --- a/cmake/Dependencies.cmake +++ b/cmake/Dependencies.cmake @@ -221,6 +221,12 @@ if (PLATFORM_EXTENSIONS) endif() endif() +if (${DESKTOP_NOTIFICATIONS}) + # snorenotify does only provide a cmake find module + find_package(LibsnoreQt5 0.7.0 REQUIRED) + set(ALL_LIBRARIES ${ALL_LIBRARIES} Snore::Libsnore) +endif() + add_definitions( -DLOG_TO_FILE=1 ) diff --git a/src/platform/desktop_notifications/desktopnotify.cpp b/src/platform/desktop_notifications/desktopnotify.cpp new file mode 100644 index 000000000..97015c792 --- /dev/null +++ b/src/platform/desktop_notifications/desktopnotify.cpp @@ -0,0 +1,81 @@ +#include "desktopnotify.h" + +#include + +#include + +DesktopNotify::DesktopNotify() + : notifyCore{Snore::SnoreCore::instance()} + , snoreIcon{":/img/icons/qtox.svg"} +{ + + notifyCore.loadPlugins(Snore::SnorePlugin::Backend); + qDebug() << "primary notification backend:" << notifyCore.primaryNotificationBackend(); + + snoreApp = Snore::Application("qTox", snoreIcon); + + notifyCore.registerApplication(snoreApp); +} + +DesktopNotify::NotificationPtr DesktopNotify::createNotification(const QString& title, + const QString& text, + Snore::Notification* old) +{ + if (old == nullptr) { + return NotificationPtr( + new Snore::Notification(snoreApp, Snore::Alert(), title, text, snoreIcon)); + } else { + return NotificationPtr(new Snore::Notification(*old, title, text, snoreIcon)); + } +} + +void DesktopNotify::notifyGroupMessage() +{ + const QString text{}; + const QString title = tr("New group message received"); + NotificationPtr newNote = createNotification(title, text); + if (!newNote) { + qDebug() << "Failed to allocate group message notification"; + return; + } + groupInvite = std::move(newNote); +} + +void DesktopNotify::notifyFriendRequest() +{ + const QString title = tr("New friend request received"); + const QString text{}; + NotificationPtr newNote = createNotification(title, text); + if (!newNote) { + qDebug() << "Failed to allocate friend message notification"; + return; + } + friendMessage = std::move(newNote); + notifyCore.broadcastNotification(*friendMessage); +} + +void DesktopNotify::notifyGroupInvite() +{ + const QString title = tr("New group invite received"); + const QString text{}; + NotificationPtr newNote = createNotification(title, text); + if (!newNote) { + qDebug() << "Failed to allocate friend message notification"; + return; + } + friendMessage = std::move(newNote); + notifyCore.broadcastNotification(*friendMessage); +} + +void DesktopNotify::notifyFriendMessage() +{ + const QString title = tr("New message received"); + const QString text{}; + NotificationPtr newNote = createNotification(title, text); + if (!newNote) { + qDebug() << "Failed to allocate friend message notification"; + return; + } + friendMessage = std::move(newNote); + notifyCore.broadcastNotification(*friendMessage); +} diff --git a/src/platform/desktop_notifications/desktopnotify.h b/src/platform/desktop_notifications/desktopnotify.h new file mode 100644 index 000000000..81c0f08c9 --- /dev/null +++ b/src/platform/desktop_notifications/desktopnotify.h @@ -0,0 +1,37 @@ +#ifndef DESKTOPNOTIFY_H +#define DESKTOPNOTIFY_H + +#include + +#include +#include + +class DesktopNotify : public QObject +{ + Q_OBJECT +public: + DesktopNotify(); + +public slots: + void notifyFriendMessage(); + void notifyGroupMessage(); + void notifyFriendRequest(); + void notifyGroupInvite(); + +private: + using NotificationPtr = std::unique_ptr; + + NotificationPtr createNotification(const QString& title, const QString& text, + Snore::Notification* old = nullptr); + +private: + Snore::SnoreCore& notifyCore; + NotificationPtr groupInvite = {nullptr}; + NotificationPtr groupMessage = {nullptr}; + NotificationPtr friendRequest = {nullptr}; + NotificationPtr friendMessage = {nullptr}; + Snore::Application snoreApp; + Snore::Icon snoreIcon; +}; + +#endif // DESKTOPNOTIFY_H diff --git a/src/widget/widget.cpp b/src/widget/widget.cpp index 7d5a7bcdd..308ea6639 100644 --- a/src/widget/widget.cpp +++ b/src/widget/widget.cpp @@ -1357,6 +1357,9 @@ bool Widget::newFriendMessageAlert(int friendId, bool sound) f->setEventFlag(true); widget->updateStatusLight(); ui->friendList->trackWidget(widget); +#if DESKTOP_NOTIFICATIONS + notifier.notifyFriendMessage(); +#endif if (contentDialog == nullptr) { if (hasActive) { @@ -1394,6 +1397,9 @@ bool Widget::newGroupMessageAlert(int groupId, bool notify) g->setEventFlag(true); widget->updateStatusLight(); +#if DESKTOP_NOTIFICATIONS + notifier.notifyGroupMessage(); +#endif if (contentDialog == nullptr) { if (hasActive) { @@ -1462,6 +1468,9 @@ void Widget::onFriendRequestReceived(const ToxPk& friendPk, const QString& messa if (addFriendForm->addFriendRequest(friendPk.toString(), message)) { friendRequestsUpdate(); newMessageAlert(window(), isActiveWindow(), true, true); +#if DESKTOP_NOTIFICATIONS + notifier.notifyFriendRequest(); +#endif } } @@ -1706,6 +1715,9 @@ void Widget::onGroupInviteReceived(const GroupInvite& inviteInfo) ++unreadGroupInvites; groupInvitesUpdate(); newMessageAlert(window(), isActiveWindow(), true, true); +#if DESKTOP_NOTIFICATIONS + notifier.notifyGroupInvite(); +#endif } } else { qWarning() << "onGroupInviteReceived: Unknown groupchat type:" << confType; diff --git a/src/widget/widget.h b/src/widget/widget.h index 6954c6fbf..a79369649 100644 --- a/src/widget/widget.h +++ b/src/widget/widget.h @@ -32,6 +32,9 @@ #include "src/core/core.h" #include "src/core/toxfile.h" #include "src/core/toxid.h" +#if DESKTOP_NOTIFICATIONS +#include "src/platform/desktop_notifications/desktopnotify.h" +#endif #define PIXELS_TO_ACT 7 @@ -298,7 +301,7 @@ private: MaskablePixmapWidget* profilePicture; bool notify(QObject* receiver, QEvent* event); bool autoAwayActive = false; - QTimer *timer; + QTimer* timer; QRegExp nameMention, sanitizedNameMention; bool eventFlag; bool eventIcon; @@ -317,6 +320,10 @@ private: QMap> groupChatrooms; QMap> groupChatForms; +#if DESKTOP_NOTIFICATIONS + DesktopNotify notifier; +#endif + #ifdef Q_OS_MAC QAction* fileMenu; QAction* editMenu;