diff --git a/brightray/browser/linux/notification_presenter_linux.cc b/brightray/browser/linux/notification_presenter_linux.cc index a3d72bc8faa..3ff75c51155 100644 --- a/brightray/browser/linux/notification_presenter_linux.cc +++ b/brightray/browser/linux/notification_presenter_linux.cc @@ -8,14 +8,52 @@ #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 "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 = NULL; + + 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; + dbus_error_free(&err); + + goto out; + } + + unity_result = dbus_bus_name_has_owner(bus, "com.canonical.indicator.session", &err); + + 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; +} + void log_and_clear_error(GError* error, const char* context) { LOG(ERROR) << context << ": domain=" << error->domain @@ -52,6 +90,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); @@ -62,8 +101,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 the indicate + // dbus service + if (!UnityIsRunning()) { + 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); + g_object_unref(pixbuf); GError* error = nullptr; notify_notification_show(notification, &error); diff --git a/brightray/browser/linux/notification_presenter_linux.h b/brightray/browser/linux/notification_presenter_linux.h index 384e2d2f8c7..ddd79e4c2e8 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 ad17cdb3c53..6c1a66fc593 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; }; diff --git a/brightray/browser/notification_presenter_mac.h b/brightray/browser/notification_presenter_mac.h index fd9dd737d9e..20cbee20e84 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 f0a08d75974..cbe25c65a46 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]; diff --git a/brightray/browser/platform_notification_service_impl.cc b/brightray/browser/platform_notification_service_impl.cc index f47d3851198..aaea4dcd610 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(