Merge pull request #16 from jendas1/OSXNotificationCenter

OS X notifications
This commit is contained in:
Patrick von Reth 2015-06-29 10:16:48 +02:00
commit 4ec563a5de
2 changed files with 86 additions and 19 deletions

View File

@ -28,9 +28,8 @@ class OSXNotificationCenter : public Snore::SnoreBackend
Q_PLUGIN_METADATA(IID "org.Snore.NotificationBackend/1.0" FILE "plugin.json") Q_PLUGIN_METADATA(IID "org.Snore.NotificationBackend/1.0" FILE "plugin.json")
public: public:
OSXNotificationCenter() = default; OSXNotificationCenter();
~OSXNotificationCenter() = default; ~OSXNotificationCenter();
bool initialize() override;
public slots: public slots:
void slotNotify(Snore::Notification notification) override; void slotNotify(Snore::Notification notification) override;

View File

@ -1,41 +1,109 @@
#include "osxnotificationcenter.h" #include "osxnotificationcenter.h"
#include "libsnore/plugins/snorebackend.h" #include "libsnore/plugins/snorebackend.h"
#include "libsnore/notification/notification_p.h"
#include "libsnore/utils.h" #include "libsnore/utils.h"
#include "libsnore/snore.h"
#import <Foundation/Foundation.h> #include "libsnore/log.h"
#import <objc/runtime.h>
#import <QThread.h> #import <QThread.h>
#import <QApplication.h> #import <QApplication.h>
#import <QMap>
#include <Foundation/Foundation.h>
using namespace Snore; using namespace Snore;
QMap<int, Notification> m_IdToNotification;
NSMutableDictionary * m_IdToNSNotification;
void emitNotificationClicked(Notification notification) {
emit SnoreCore::instance().actionInvoked(notification);
}
//
// Enable reaction when user clicks on NSUserNotification
//
@interface UserNotificationItem : NSObject<NSUserNotificationCenterDelegate> { }
- (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) // store some variables that are needed (since obj-c++ does not allow having obj-c classes as c++ members)
namespace { namespace {
NSUserNotificationCenter *notification_center;
NSString *NSStringFromQString(QString qstr) { NSString * NSStringFromQString(QString qstr) {
return [NSString stringWithUTF8String: qstr.toUtf8().data()]; 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) void OSXNotificationCenter::slotNotify(Snore::Notification notification)
{ {
NSUserNotification *osx_notification = [[NSUserNotification alloc] init]; NSUserNotification * osxNotification = [[[NSUserNotification alloc] init] autorelease];
osx_notification.title = NSStringFromQString(Utils::toPlainText(notification.title())); NSString * notificationId = [NSString stringWithFormat:@"%d",notification.id()];
osx_notification.informativeText = NSStringFromQString(Utils::toPlainText(notification.text())); 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); slotNotificationDisplayed(notification);
[notification_center deliverNotification: osx_notification];
[osx_notification release];
} }