diff --git a/src/plugins/backends/osxnotificationcenter/osxnotificationcenter.h b/src/plugins/backends/osxnotificationcenter/osxnotificationcenter.h index d3c7df8..6abaa96 100644 --- a/src/plugins/backends/osxnotificationcenter/osxnotificationcenter.h +++ b/src/plugins/backends/osxnotificationcenter/osxnotificationcenter.h @@ -28,9 +28,8 @@ class OSXNotificationCenter : public Snore::SnoreBackend Q_PLUGIN_METADATA(IID "org.Snore.NotificationBackend/1.0" FILE "plugin.json") public: - OSXNotificationCenter() = default; - ~OSXNotificationCenter() = default; - bool initialize() override; + OSXNotificationCenter(); + ~OSXNotificationCenter(); public slots: void slotNotify(Snore::Notification notification) override; diff --git a/src/plugins/backends/osxnotificationcenter/osxnotificationcenter.mm b/src/plugins/backends/osxnotificationcenter/osxnotificationcenter.mm index 72656ff..97b2876 100644 --- a/src/plugins/backends/osxnotificationcenter/osxnotificationcenter.mm +++ b/src/plugins/backends/osxnotificationcenter/osxnotificationcenter.mm @@ -1,41 +1,109 @@ #include "osxnotificationcenter.h" #include "libsnore/plugins/snorebackend.h" +#include "libsnore/notification/notification_p.h" #include "libsnore/utils.h" - -#import -#import +#include "libsnore/snore.h" +#include "libsnore/log.h" #import #import +#import +#include using namespace Snore; +QMap m_IdToNotification; +NSMutableDictionary * m_IdToNSNotification; + + +void emitNotificationClicked(Notification notification) { + emit SnoreCore::instance().actionInvoked(notification); +} + +// +// Enable reaction when user clicks on NSUserNotification +// + +@interface UserNotificationItem : NSObject { } + +- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification; +@end + +@implementation UserNotificationItem +- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification { + Q_UNUSED(center); + Q_UNUSED(notification); + return YES; +} +- (void) userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification +{ + + snoreDebug(SNORE_DEBUG) << "User clicked on notification"; + int notificationId = [notification.userInfo[@"id"] intValue]; + [center removeDeliveredNotification: notification]; + if (not m_IdToNotification.contains(notificationId)) { + snoreDebug(SNORE_WARNING) << "User clicked on notification that was not recognized"; + return; + } + auto snoreNotification = m_IdToNotification.take(notificationId); + snoreNotification.data()->setCloseReason(Notification::ACTIVATED); + emitNotificationClicked(snoreNotification); +} +@end + +class UserNotificationItemClass +{ +public: + UserNotificationItemClass() { + item = [UserNotificationItem alloc]; + if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) { + [[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:item]; + } + } + ~UserNotificationItemClass() { + if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) { + [[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:nil]; + } + [item release]; + } + UserNotificationItem *item; +}; + + // store some variables that are needed (since obj-c++ does not allow having obj-c classes as c++ members) namespace { - NSUserNotificationCenter *notification_center; - - NSString *NSStringFromQString(QString qstr) { + + NSString * NSStringFromQString(QString qstr) { return [NSString stringWithUTF8String: qstr.toUtf8().data()]; } } +UserNotificationItemClass * delegate; -bool OSXNotificationCenter::initialize() +OSXNotificationCenter::OSXNotificationCenter() { - notification_center = [NSUserNotificationCenter defaultUserNotificationCenter]; + m_IdToNSNotification = [[[NSMutableDictionary alloc] init] autorelease]; + delegate = new UserNotificationItemClass(); +} - return SnoreBackend::initialize(); +OSXNotificationCenter::~OSXNotificationCenter() +{ + delete delegate; } void OSXNotificationCenter::slotNotify(Snore::Notification notification) { - NSUserNotification *osx_notification = [[NSUserNotification alloc] init]; - osx_notification.title = NSStringFromQString(Utils::toPlainText(notification.title())); - osx_notification.informativeText = NSStringFromQString(Utils::toPlainText(notification.text())); + NSUserNotification * osxNotification = [[[NSUserNotification alloc] init] autorelease]; + NSString * notificationId = [NSString stringWithFormat:@"%d",notification.id()]; + osxNotification.title = NSStringFromQString(notification.title()); + osxNotification.userInfo = [NSDictionary dictionaryWithObjectsAndKeys:notificationId, @"id", nil]; + osxNotification.informativeText = NSStringFromQString(notification.text()); + + // Add notification to mapper from id to Nofification / NSUserNotification + m_IdToNotification.insert(notification.id(), notification); + [m_IdToNSNotification setObject:osxNotification forKey: notificationId]; + [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification: osxNotification]; + slotNotificationDisplayed(notification); - - [notification_center deliverNotification: osx_notification]; - - [osx_notification release]; }