New: OS X notifications are now working again

This commit is contained in:
jendas 2015-06-28 22:27:22 +02:00
parent 1e2d675b57
commit 89b3b0ad3f
2 changed files with 90 additions and 17 deletions

View File

@ -28,8 +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; bool initialize() override;
public slots: public slots:

View File

@ -1,41 +1,114 @@
#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> id_to_notification;
NSMutableDictionary * id_to_nsnotification;
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 notification_id = [notification.userInfo[@"id"] intValue];
[center removeDeliveredNotification: notification];
if (not id_to_notification.contains(notification_id)) {
snoreDebug(SNORE_WARNING) << "User clicked on notification that was not recognized";
return;
}
Notification snore_notification = id_to_notification[notification_id];
snore_notification.data()->setCloseReason(Notification::ACTIVATED);
emitNotificationClicked(snore_notification);
}
@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;
OSXNotificationCenter::OSXNotificationCenter()
{
id_to_nsnotification = [[[NSMutableDictionary alloc] init] autorelease];
delegate = new UserNotificationItemClass();
}
OSXNotificationCenter::~OSXNotificationCenter()
{
delete delegate;
}
bool OSXNotificationCenter::initialize() bool OSXNotificationCenter::initialize()
{ {
notification_center = [NSUserNotificationCenter defaultUserNotificationCenter];
return SnoreBackend::initialize(); return SnoreBackend::initialize();
} }
void OSXNotificationCenter::slotNotify(Snore::Notification notification) void OSXNotificationCenter::slotNotify(Snore::Notification notification)
{ {
NSUserNotification *osx_notification = [[NSUserNotification alloc] init]; NSUserNotification * osx_notification = [[[NSUserNotification alloc] init] autorelease];
osx_notification.title = NSStringFromQString(Utils::toPlainText(notification.title())); NSString * notification_id = [NSString stringWithFormat:@"%d",notification.id()];
osx_notification.informativeText = NSStringFromQString(Utils::toPlainText(notification.text())); osx_notification.title = NSStringFromQString(notification.title());
osx_notification.userInfo = [NSDictionary dictionaryWithObjectsAndKeys:notification_id, @"id", nil];
osx_notification.informativeText = NSStringFromQString(notification.text());
// Add notification to mapper from id to Nofification / NSUserNotification
id_to_notification.insert(notification.id(), notification);
[id_to_nsnotification setObject:osx_notification forKey: notification_id];
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification: osx_notification];
slotNotificationDisplayed(notification); slotNotificationDisplayed(notification);
[notification_center deliverNotification: osx_notification];
[osx_notification release];
} }