diff options
author | Remko Tronçon <git@el-tramo.be> | 2012-03-09 11:22:00 (GMT) |
---|---|---|
committer | Remko Tronçon <git@el-tramo.be> | 2012-03-09 11:22:00 (GMT) |
commit | c83da56f6c93db3dc8040be1137fd40a08bf4132 (patch) | |
tree | c4141dc2f333a6517a5dbc70c04c013878bee1bf | |
parent | 0833f7da453db9cd0fc3a78c793e7532663ab86b (diff) | |
download | swift-contrib-c83da56f6c93db3dc8040be1137fd40a08bf4132.zip swift-contrib-c83da56f6c93db3dc8040be1137fd40a08bf4132.tar.bz2 |
Handle double growl callbacks.
-rw-r--r-- | BuildTools/SCons/SConstruct | 2 | ||||
-rw-r--r-- | SwifTools/Notifier/GrowlNotifier.h | 1 | ||||
-rw-r--r-- | SwifTools/Notifier/GrowlNotifier.mm | 28 |
3 files changed, 25 insertions, 6 deletions
diff --git a/BuildTools/SCons/SConstruct b/BuildTools/SCons/SConstruct index 1412b56..b3d3c8f 100644 --- a/BuildTools/SCons/SConstruct +++ b/BuildTools/SCons/SConstruct @@ -242,7 +242,7 @@ if env["PLATFORM"] == "darwin" : growl_env = conf_env.Clone() growl_env.MergeFlags(growl_flags) conf = Configure(growl_env, custom_tests = { "CheckObjCHeader" : checkObjCHeader }) - if False and conf.CheckObjCHeader("Growl/Growl.h") : + if conf.CheckObjCHeader("Growl/Growl.h") : env["HAVE_GROWL"] = 1 env["GROWL_FLAGS"] = growl_flags env["GROWL_FRAMEWORK"] = "/Library/Frameworks/Growl.framework" diff --git a/SwifTools/Notifier/GrowlNotifier.h b/SwifTools/Notifier/GrowlNotifier.h index cb0d089..f4e6803 100644 --- a/SwifTools/Notifier/GrowlNotifier.h +++ b/SwifTools/Notifier/GrowlNotifier.h @@ -20,6 +20,7 @@ namespace Swift { class GrowlNotifier : public Notifier { public: GrowlNotifier(const std::string& name); + ~GrowlNotifier(); virtual void showMessage(Type type, const std::string& subject, const std::string& description, const boost::filesystem::path& picture, boost::function<void()> callback); virtual bool isExternallyConfigured() const; diff --git a/SwifTools/Notifier/GrowlNotifier.mm b/SwifTools/Notifier/GrowlNotifier.mm index cb4790e..31eabd3 100644 --- a/SwifTools/Notifier/GrowlNotifier.mm +++ b/SwifTools/Notifier/GrowlNotifier.mm @@ -7,6 +7,7 @@ #include <SwifTools/Notifier/GrowlNotifier.h> #include <boost/smart_ptr/make_shared.hpp> +#include <set> #include <SwifTools/Notifier/GrowlNotifierDelegate.h> #include <SwifTools/Cocoa/CocoaUtil.h> @@ -27,6 +28,7 @@ namespace Swift { class GrowlNotifier::Private { public: + std::set<Context*> pendingNotifications; boost::intrusive_ptr<GrowlNotifierDelegate> delegate; }; @@ -55,12 +57,23 @@ GrowlNotifier::GrowlNotifier(const std::string& name) { [GrowlApplicationBridge setGrowlDelegate: p->delegate.get()]; } +GrowlNotifier::~GrowlNotifier() { + [GrowlApplicationBridge setGrowlDelegate: nil]; + foreach (Context* context, p->pendingNotifications) { + delete context; + } + p->pendingNotifications.clear(); +} + void GrowlNotifier::showMessage(Type type, const std::string& subject, const std::string& description, const boost::filesystem::path& picturePath, boost::function<void()> callback) { ByteArray picture; readByteArrayFromFile(picture, picturePath.string()); Context* context = new Context(callback); - + // Growl sometimes sends timeout notifications twice for the same message. We therefore need + // to keep track of which ones have already been processed. + p->pendingNotifications.insert(context); + [GrowlApplicationBridge notifyWithTitle: STD2NSSTRING(subject) description: STD2NSSTRING(description) @@ -73,14 +86,19 @@ void GrowlNotifier::showMessage(Type type, const std::string& subject, const std void GrowlNotifier::handleNotificationClicked(void* rawData) { Context* context = *(Context**) [((NSData*) rawData) bytes]; - if (!context->callback->empty()) { - (*context->callback)(); + if (p->pendingNotifications.erase(context) > 0) { + if (!context->callback->empty()) { + (*context->callback)(); + } + delete context; } - delete context; } void GrowlNotifier::handleNotificationTimedOut(void* rawData) { - delete *(Context**) [((NSData*) rawData) bytes]; + Context* context = *(Context**) [((NSData*) rawData) bytes]; + if (p->pendingNotifications.erase(context) > 0) { + delete context; + } } bool GrowlNotifier::isExternallyConfigured() const { |