From b8689dc6cce86065120fcedc15d0d006d1a00120 Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Mon, 20 Apr 2015 13:20:50 -0700 Subject: [PATCH 1/6] Add a parameter to ShowNotification for the icon --- brightray/browser/linux/notification_presenter_linux.cc | 1 + brightray/browser/linux/notification_presenter_linux.h | 1 + brightray/browser/notification_presenter.h | 3 +++ 3 files changed, 5 insertions(+) diff --git a/brightray/browser/linux/notification_presenter_linux.cc b/brightray/browser/linux/notification_presenter_linux.cc index a3d72bc8faa2..45c5c7d9f6b3 100644 --- a/brightray/browser/linux/notification_presenter_linux.cc +++ b/brightray/browser/linux/notification_presenter_linux.cc @@ -52,6 +52,7 @@ NotificationPresenterLinux::~NotificationPresenterLinux() { void NotificationPresenterLinux::ShowNotification( const content::PlatformNotificationData& data, + const SkBitmap& icon, scoped_ptr delegate_ptr, base::Closure* cancel_callback) { std::string title = base::UTF16ToUTF8(data.title); diff --git a/brightray/browser/linux/notification_presenter_linux.h b/brightray/browser/linux/notification_presenter_linux.h index 384e2d2f8c7a..ddd79e4c2e8d 100644 --- a/brightray/browser/linux/notification_presenter_linux.h +++ b/brightray/browser/linux/notification_presenter_linux.h @@ -27,6 +27,7 @@ class NotificationPresenterLinux : public NotificationPresenter { // NotificationPresenter: void ShowNotification( const content::PlatformNotificationData&, + const SkBitmap& icon, scoped_ptr delegate, base::Closure* cancel_callback) override; diff --git a/brightray/browser/notification_presenter.h b/brightray/browser/notification_presenter.h index ad17cdb3c531..6c1a66fc5931 100644 --- a/brightray/browser/notification_presenter.h +++ b/brightray/browser/notification_presenter.h @@ -4,6 +4,8 @@ #include "base/callback_forward.h" #include "base/memory/scoped_ptr.h" +class SkBitmap; + namespace content { class DesktopNotificationDelegate; struct PlatformNotificationData; @@ -19,6 +21,7 @@ class NotificationPresenter { virtual void ShowNotification( const content::PlatformNotificationData&, + const SkBitmap& icon, scoped_ptr delegate, base::Closure* cancel_callback) = 0; }; From a31ce8ce5020156b96f8207a3ec0650c603b2c98 Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Mon, 20 Apr 2015 13:21:18 -0700 Subject: [PATCH 2/6] Make PlatformNotificationService pass along the icon --- brightray/browser/platform_notification_service_impl.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/brightray/browser/platform_notification_service_impl.cc b/brightray/browser/platform_notification_service_impl.cc index f47d3851198d..aaea4dcd6108 100644 --- a/brightray/browser/platform_notification_service_impl.cc +++ b/brightray/browser/platform_notification_service_impl.cc @@ -44,7 +44,7 @@ void PlatformNotificationServiceImpl::DisplayNotification( base::Closure* cancel_callback) { auto presenter = notification_presenter(); if (presenter) - presenter->ShowNotification(notification_data, delegate.Pass(), cancel_callback); + presenter->ShowNotification(notification_data, icon, delegate.Pass(), cancel_callback); } void PlatformNotificationServiceImpl::DisplayPersistentNotification( From 3357dc0ef76435576cd94ca76bbc9fc95b8da548 Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Mon, 20 Apr 2015 13:22:18 -0700 Subject: [PATCH 3/6] Set icon for notification, and disable action on Ubuntu --- .../linux/notification_presenter_linux.cc | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/brightray/browser/linux/notification_presenter_linux.cc b/brightray/browser/linux/notification_presenter_linux.cc index 45c5c7d9f6b3..88f0dcef9d5d 100644 --- a/brightray/browser/linux/notification_presenter_linux.cc +++ b/brightray/browser/linux/notification_presenter_linux.cc @@ -8,10 +8,13 @@ #include "base/bind.h" #include "base/logging.h" #include "base/strings/utf_string_conversions.h" +#include "chrome/browser/ui/libgtk2ui/skia_utils_gtk2.h" #include "content/public/browser/desktop_notification_delegate.h" #include "content/public/common/platform_notification_data.h" #include "common/application_info.h" +#include + namespace brightray { namespace { @@ -63,8 +66,20 @@ void NotificationPresenterLinux::ShowNotification( g_object_set_data_full(G_OBJECT(notification), "delegate", delegate, operator delete); g_signal_connect(notification, "closed", G_CALLBACK(OnNotificationClosedThunk), this); - notify_notification_add_action(notification, "default", "View", OnNotificationViewThunk, this, - nullptr); + + // NB: On Unity, adding a notification action will cause the notification + // to display as a modal dialog box. Testing for distros that have "Unity + // Zen Nature" is difficult, we will test for the presence of libindicate, + // an Unity-only library. + struct stat dontcare; + if (stat("/usr/lib/libindicate.so", &dontcare)) { + notify_notification_add_action(notification, "default", "View", OnNotificationViewThunk, this, nullptr); + } + + GdkPixbuf* pixbuf = libgtk2ui::GdkPixbufFromSkBitmap(icon); + + notify_notification_set_image_from_pixbuf(notification, pixbuf); + notify_notification_set_timeout(notification, NOTIFY_EXPIRES_DEFAULT); GError* error = nullptr; notify_notification_show(notification, &error); From 7c52838ece13c80760a4e0e44ef6e044d6e1b40b Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Mon, 20 Apr 2015 13:29:10 -0700 Subject: [PATCH 4/6] Fix the build on OS X --- brightray/browser/notification_presenter_mac.h | 1 + brightray/browser/notification_presenter_mac.mm | 1 + 2 files changed, 2 insertions(+) diff --git a/brightray/browser/notification_presenter_mac.h b/brightray/browser/notification_presenter_mac.h index fd9dd737d9e0..20cbee20e842 100644 --- a/brightray/browser/notification_presenter_mac.h +++ b/brightray/browser/notification_presenter_mac.h @@ -23,6 +23,7 @@ class NotificationPresenterMac : public NotificationPresenter { // NotificationPresenter: void ShowNotification( const content::PlatformNotificationData&, + const SkBitmap& icon, scoped_ptr delegate, base::Closure* cancel_callback) override; diff --git a/brightray/browser/notification_presenter_mac.mm b/brightray/browser/notification_presenter_mac.mm index f0a08d759742..cbe25c65a469 100644 --- a/brightray/browser/notification_presenter_mac.mm +++ b/brightray/browser/notification_presenter_mac.mm @@ -41,6 +41,7 @@ NotificationPresenterMac::~NotificationPresenterMac() { void NotificationPresenterMac::ShowNotification( const content::PlatformNotificationData& data, + const SkBitmap& icon, scoped_ptr delegate, base::Closure* cancel_callback) { auto notification = [[NSUserNotification alloc] init]; From 5d82bab10d8cbd81d8aa649ef18fae6887df243e Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Mon, 20 Apr 2015 15:31:24 -0700 Subject: [PATCH 5/6] Use DBus to detect indicator, not testing for files like an animal --- .../linux/notification_presenter_linux.cc | 42 ++++++++++++++++--- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/brightray/browser/linux/notification_presenter_linux.cc b/brightray/browser/linux/notification_presenter_linux.cc index 88f0dcef9d5d..1995fce2f27b 100644 --- a/brightray/browser/linux/notification_presenter_linux.cc +++ b/brightray/browser/linux/notification_presenter_linux.cc @@ -12,13 +12,44 @@ #include "content/public/browser/desktop_notification_delegate.h" #include "content/public/common/platform_notification_data.h" #include "common/application_info.h" - -#include +#include "dbus/dbus.h" namespace brightray { namespace { +static bool unity_has_result = false; +static bool unity_result = false; + +static bool UnityIsRunning() { + if (unity_has_result) { + return unity_result; + } + + struct DBusError err; + struct DBusConnection* bus; + + dbus_error_init(&err); + + bus = dbus_bus_get(DBUS_BUS_SESSION, &err); + if (dbus_error_is_set(&err)) { + g_debug("Failed to get Session Bus reference"); + unity_result = false; + + goto out; + } + + unity_result = dbus_bus_name_has_owner(bus, "com.canonical.indicator.session", &err); + + if (dbus_error_is_set(&err)) { + unity_result = false; + } + +out: + unity_has_result = true; + return unity_result; +} + void log_and_clear_error(GError* error, const char* context) { LOG(ERROR) << context << ": domain=" << error->domain @@ -69,10 +100,9 @@ void NotificationPresenterLinux::ShowNotification( // NB: On Unity, adding a notification action will cause the notification // to display as a modal dialog box. Testing for distros that have "Unity - // Zen Nature" is difficult, we will test for the presence of libindicate, - // an Unity-only library. - struct stat dontcare; - if (stat("/usr/lib/libindicate.so", &dontcare)) { + // Zen Nature" is difficult, we will test for the presence of the indicate + // dbus service + if (!UnityIsRunning()) { notify_notification_add_action(notification, "default", "View", OnNotificationViewThunk, this, nullptr); } From a0e5d36305e1d8bd8176c78fac3fef10c30bf99e Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Tue, 21 Apr 2015 14:09:48 -0700 Subject: [PATCH 6/6] Free some stuff --- brightray/browser/linux/notification_presenter_linux.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/brightray/browser/linux/notification_presenter_linux.cc b/brightray/browser/linux/notification_presenter_linux.cc index 1995fce2f27b..3ff75c51155a 100644 --- a/brightray/browser/linux/notification_presenter_linux.cc +++ b/brightray/browser/linux/notification_presenter_linux.cc @@ -27,7 +27,7 @@ static bool UnityIsRunning() { } struct DBusError err; - struct DBusConnection* bus; + struct DBusConnection* bus = NULL; dbus_error_init(&err); @@ -35,6 +35,7 @@ static bool UnityIsRunning() { if (dbus_error_is_set(&err)) { g_debug("Failed to get Session Bus reference"); unity_result = false; + dbus_error_free(&err); goto out; } @@ -43,9 +44,12 @@ static bool UnityIsRunning() { if (dbus_error_is_set(&err)) { unity_result = false; + dbus_error_free(&err); } out: + if (bus) dbus_connection_unref(bus); + unity_has_result = true; return unity_result; } @@ -110,6 +114,7 @@ void NotificationPresenterLinux::ShowNotification( notify_notification_set_image_from_pixbuf(notification, pixbuf); notify_notification_set_timeout(notification, NOTIFY_EXPIRES_DEFAULT); + g_object_unref(pixbuf); GError* error = nullptr; notify_notification_show(notification, &error);