osx: make use of the 10.8+ user notification center to display growl like notifications
- if 10.8, use user notification center, if <10.8, use growl Signed-off-by: Jonas Schnelli <jonas.schnelli@include7.ch>
This commit is contained in:
parent
5b5d399593
commit
b4b0170595
|
@ -393,8 +393,8 @@ win32:!contains(MINGW_THREAD_BUGFIX, 0) {
|
||||||
DEFINES += _FILE_OFFSET_BITS=64
|
DEFINES += _FILE_OFFSET_BITS=64
|
||||||
}
|
}
|
||||||
|
|
||||||
macx:HEADERS += src/qt/macdockiconhandler.h
|
macx:HEADERS += src/qt/macdockiconhandler.h src/qt/macnotificationhandler.h
|
||||||
macx:OBJECTIVE_SOURCES += src/qt/macdockiconhandler.mm
|
macx:OBJECTIVE_SOURCES += src/qt/macdockiconhandler.mm src/qt/macnotificationhandler.mm
|
||||||
macx:LIBS += -framework Foundation -framework ApplicationServices -framework AppKit
|
macx:LIBS += -framework Foundation -framework ApplicationServices -framework AppKit
|
||||||
macx:DEFINES += MAC_OSX MSG_NOSIGNAL=0
|
macx:DEFINES += MAC_OSX MSG_NOSIGNAL=0
|
||||||
macx:ICON = src/qt/res/icons/bitcoin.icns
|
macx:ICON = src/qt/res/icons/bitcoin.icns
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef MACNOTIFICATIONHANDLER_H
|
||||||
|
#define MACNOTIFICATIONHANDLER_H
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
/** Macintosh-specific notification handler (supports UserNotificationCenter and Growl).
|
||||||
|
*/
|
||||||
|
class MacNotificationHandler : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
/** shows a 10.8+ UserNotification in the UserNotificationCenter
|
||||||
|
*/
|
||||||
|
void showNotification(const QString &title, const QString &text);
|
||||||
|
|
||||||
|
/** executes AppleScript */
|
||||||
|
void sendAppleScript(const QString &script);
|
||||||
|
|
||||||
|
/** check if OS can handle UserNotifications */
|
||||||
|
bool hasUserNotificationCenterSupport(void);
|
||||||
|
static MacNotificationHandler *instance();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // MACNOTIFICATIONHANDLER_H
|
|
@ -0,0 +1,65 @@
|
||||||
|
#include "macnotificationhandler.h"
|
||||||
|
|
||||||
|
#undef slots
|
||||||
|
#include <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
void MacNotificationHandler::showNotification(const QString &title, const QString &text)
|
||||||
|
{
|
||||||
|
// check if users OS has support for NSUserNotification
|
||||||
|
if(this->hasUserNotificationCenterSupport()) {
|
||||||
|
// okay, seems like 10.8+
|
||||||
|
QByteArray utf8 = title.toUtf8();
|
||||||
|
char* cString = (char *)utf8.constData();
|
||||||
|
NSString *titleMac = [[NSString alloc] initWithUTF8String:cString];
|
||||||
|
|
||||||
|
utf8 = text.toUtf8();
|
||||||
|
cString = (char *)utf8.constData();
|
||||||
|
NSString *textMac = [[NSString alloc] initWithUTF8String:cString];
|
||||||
|
|
||||||
|
// do everything weak linked (because we will keep <10.8 compatibility)
|
||||||
|
id userNotification = [[NSClassFromString(@"NSUserNotification") alloc] init];
|
||||||
|
[userNotification performSelector:@selector(setTitle:) withObject:titleMac];
|
||||||
|
[userNotification performSelector:@selector(setInformativeText:) withObject:textMac];
|
||||||
|
|
||||||
|
id notificationCenterInstance = [NSClassFromString(@"NSUserNotificationCenter") performSelector:@selector(defaultUserNotificationCenter)];
|
||||||
|
[notificationCenterInstance performSelector:@selector(deliverNotification:) withObject:userNotification];
|
||||||
|
|
||||||
|
[titleMac release];
|
||||||
|
[textMac release];
|
||||||
|
[userNotification release];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// sendAppleScript just take a QString and executes it as apple script
|
||||||
|
void MacNotificationHandler::sendAppleScript(const QString &script)
|
||||||
|
{
|
||||||
|
QByteArray utf8 = script.toUtf8();
|
||||||
|
char* cString = (char *)utf8.constData();
|
||||||
|
NSString *scriptApple = [[NSString alloc] initWithUTF8String:cString];
|
||||||
|
|
||||||
|
NSAppleScript *as = [[NSAppleScript alloc] initWithSource:scriptApple];
|
||||||
|
NSDictionary *err = nil;
|
||||||
|
[as executeAndReturnError:&err];
|
||||||
|
[as release];
|
||||||
|
[scriptApple release];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MacNotificationHandler::hasUserNotificationCenterSupport(void)
|
||||||
|
{
|
||||||
|
Class possibleClass = NSClassFromString(@"NSUserNotificationCenter");
|
||||||
|
|
||||||
|
// check if users OS has support for NSUserNotification
|
||||||
|
if(possibleClass!=nil) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MacNotificationHandler *MacNotificationHandler::instance()
|
||||||
|
{
|
||||||
|
static MacNotificationHandler *s_instance = NULL;
|
||||||
|
if (!s_instance)
|
||||||
|
s_instance = new MacNotificationHandler();
|
||||||
|
return s_instance;
|
||||||
|
}
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
#include <ApplicationServices/ApplicationServices.h>
|
#include <ApplicationServices/ApplicationServices.h>
|
||||||
extern bool qt_mac_execute_apple_script(const QString &script, AEDesc *ret);
|
#include "macnotificationhandler.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// https://wiki.ubuntu.com/NotificationDevelopmentGuidelines recommends at least 128
|
// https://wiki.ubuntu.com/NotificationDevelopmentGuidelines recommends at least 128
|
||||||
|
@ -47,6 +47,11 @@ Notificator::Notificator(const QString &programName, QSystemTrayIcon *trayicon,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
|
// check if users OS has support for NSUserNotification
|
||||||
|
if( MacNotificationHandler::instance()->hasUserNotificationCenterSupport()) {
|
||||||
|
mode = UserNotificationCenter;
|
||||||
|
}
|
||||||
|
else {
|
||||||
// Check if Growl is installed (based on Qt's tray icon implementation)
|
// Check if Growl is installed (based on Qt's tray icon implementation)
|
||||||
CFURLRef cfurl;
|
CFURLRef cfurl;
|
||||||
OSStatus status = LSGetApplicationForInfo(kLSUnknownType, kLSUnknownCreator, CFSTR("growlTicket"), kLSRolesAll, 0, &cfurl);
|
OSStatus status = LSGetApplicationForInfo(kLSUnknownType, kLSUnknownCreator, CFSTR("growlTicket"), kLSRolesAll, 0, &cfurl);
|
||||||
|
@ -61,6 +66,7 @@ Notificator::Notificator(const QString &programName, QSystemTrayIcon *trayicon,
|
||||||
CFRelease(cfurl);
|
CFRelease(cfurl);
|
||||||
CFRelease(bundle);
|
CFRelease(bundle);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,8 +275,14 @@ void Notificator::notifyGrowl(Class cls, const QString &title, const QString &te
|
||||||
quotedTitle.replace("\\", "\\\\").replace("\"", "\\");
|
quotedTitle.replace("\\", "\\\\").replace("\"", "\\");
|
||||||
quotedText.replace("\\", "\\\\").replace("\"", "\\");
|
quotedText.replace("\\", "\\\\").replace("\"", "\\");
|
||||||
QString growlApp(this->mode == Notificator::Growl13 ? "Growl" : "GrowlHelperApp");
|
QString growlApp(this->mode == Notificator::Growl13 ? "Growl" : "GrowlHelperApp");
|
||||||
qt_mac_execute_apple_script(script.arg(notificationApp, quotedTitle, quotedText, notificationIcon, growlApp), 0);
|
MacNotificationHandler::instance()->sendAppleScript(script.arg(notificationApp, quotedTitle, quotedText, notificationIcon, growlApp));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Notificator::notifyMacUserNotificationCenter(Class cls, const QString &title, const QString &text, const QIcon &icon) {
|
||||||
|
// icon is not supported by the user notification center yet. OSX will use the app icon.
|
||||||
|
MacNotificationHandler::instance()->showNotification(title, text);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void Notificator::notify(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout)
|
void Notificator::notify(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout)
|
||||||
|
@ -286,6 +298,9 @@ void Notificator::notify(Class cls, const QString &title, const QString &text, c
|
||||||
notifySystray(cls, title, text, icon, millisTimeout);
|
notifySystray(cls, title, text, icon, millisTimeout);
|
||||||
break;
|
break;
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
|
case UserNotificationCenter:
|
||||||
|
notifyMacUserNotificationCenter(cls, title, text, icon);
|
||||||
|
break;
|
||||||
case Growl12:
|
case Growl12:
|
||||||
case Growl13:
|
case Growl13:
|
||||||
notifyGrowl(cls, title, text, icon);
|
notifyGrowl(cls, title, text, icon);
|
||||||
|
|
|
@ -50,7 +50,8 @@ private:
|
||||||
Freedesktop, /**< Use DBus org.freedesktop.Notifications */
|
Freedesktop, /**< Use DBus org.freedesktop.Notifications */
|
||||||
QSystemTray, /**< Use QSystemTray::showMessage */
|
QSystemTray, /**< Use QSystemTray::showMessage */
|
||||||
Growl12, /**< Use the Growl 1.2 notification system (Mac only) */
|
Growl12, /**< Use the Growl 1.2 notification system (Mac only) */
|
||||||
Growl13 /**< Use the Growl 1.3 notification system (Mac only) */
|
Growl13, /**< Use the Growl 1.3 notification system (Mac only) */
|
||||||
|
UserNotificationCenter /**< Use the 10.8+ User Notification Center (Mac only) */
|
||||||
};
|
};
|
||||||
QString programName;
|
QString programName;
|
||||||
Mode mode;
|
Mode mode;
|
||||||
|
@ -63,6 +64,7 @@ private:
|
||||||
void notifySystray(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout);
|
void notifySystray(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout);
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
void notifyGrowl(Class cls, const QString &title, const QString &text, const QIcon &icon);
|
void notifyGrowl(Class cls, const QString &title, const QString &text, const QIcon &icon);
|
||||||
|
void notifyMacUserNotificationCenter(Class cls, const QString &title, const QString &text, const QIcon &icon);
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue