Blob Blame History Raw
# HG changeset patch
# Parent 531e0bc755b2335dec5aae2a10f4ba454307981d
# User Martin Stransky <stransky@redhat.com>
Bug 858919 - Fixes image loading for libnotify notifications. r=?karlt

diff --git a/toolkit/system/gnome/nsAlertsIconListener.cpp b/toolkit/system/gnome/nsAlertsIconListener.cpp
--- a/toolkit/system/gnome/nsAlertsIconListener.cpp
+++ b/toolkit/system/gnome/nsAlertsIconListener.cpp
@@ -46,16 +46,31 @@ static void notify_closed_marshal(GClosu
   NS_ABORT_IF_FALSE(n_param_values >= 1, "No object in params");
 
   nsAlertsIconListener* alert =
     static_cast<nsAlertsIconListener*>(closure->data);
   alert->SendClosed();
   NS_RELEASE(alert);
 }
 
+static GdkPixbuf*
+GetPixbufFromImgRequest(imgIRequest* aRequest)
+{
+  nsCOMPtr<imgIContainer> image;
+  nsresult rv = aRequest->GetImage(getter_AddRefs(image));
+  if (NS_FAILED(rv)) {  
+    return nullptr;
+  }
+
+  nsCOMPtr<nsIImageToPixbuf> imgToPixbuf =
+    do_GetService("@mozilla.org/widget/image-to-gdk-pixbuf;1");
+
+  return imgToPixbuf->ConvertImageToPixbuf(image);
+}
+
 NS_IMPL_ISUPPORTS(nsAlertsIconListener, imgINotificationObserver,
                   nsIObserver, nsISupportsWeakReference)
 
 nsAlertsIconListener::nsAlertsIconListener()
 : mLoadedFrame(false),
   mNotification(nullptr)
 {
   if (!libNotifyHandle && !libNotifyNotAvail) {
@@ -101,57 +116,55 @@ nsAlertsIconListener::Notify(imgIRequest
   }
 
   return NS_OK;
 }
 
 nsresult
 nsAlertsIconListener::OnStopRequest(imgIRequest* aRequest)
 {
+  NS_ASSERTION(mIconRequest == aRequest, "aRequest does not match!");
+
   uint32_t imgStatus = imgIRequest::STATUS_ERROR;
   nsresult rv = aRequest->GetImageStatus(&imgStatus);
   NS_ENSURE_SUCCESS(rv, rv);
   if (imgStatus == imgIRequest::STATUS_ERROR && !mLoadedFrame) {
     // We have an error getting the image. Display the notification with no icon.
     ShowAlert(nullptr);
-  }
 
-  if (mIconRequest) {
+    // Cancel any pending request
     mIconRequest->Cancel(NS_BINDING_ABORTED);
     mIconRequest = nullptr;
   }
+
   return NS_OK;
 }
 
 nsresult
 nsAlertsIconListener::OnStopFrame(imgIRequest* aRequest)
 {
-  if (aRequest != mIconRequest)
-    return NS_ERROR_FAILURE;
+  NS_ASSERTION(mIconRequest == aRequest, "aRequest does not match!");
 
   if (mLoadedFrame)
     return NS_OK; // only use one frame
 
-  nsCOMPtr<imgIContainer> image;
-  nsresult rv = aRequest->GetImage(getter_AddRefs(image));
-  if (NS_FAILED(rv))
-    return rv;
-
-  nsCOMPtr<nsIImageToPixbuf> imgToPixbuf =
-    do_GetService("@mozilla.org/widget/image-to-gdk-pixbuf;1");
-
-  GdkPixbuf* imagePixbuf = imgToPixbuf->ConvertImageToPixbuf(image);
-  if (!imagePixbuf)
-    return NS_ERROR_FAILURE;
-
-  ShowAlert(imagePixbuf);
-
-  g_object_unref(imagePixbuf);
+  GdkPixbuf* imagePixbuf = GetPixbufFromImgRequest(aRequest);
+  if (!imagePixbuf) {
+    ShowAlert(nullptr);
+  } else {
+    ShowAlert(imagePixbuf);
+    g_object_unref(imagePixbuf);
+  }
 
   mLoadedFrame = true;
+
+  // Cancel any pending request (multipart image loading/decoding for instance)
+  mIconRequest->Cancel(NS_BINDING_ABORTED);
+  mIconRequest = nullptr;
+
   return NS_OK;
 }
 
 nsresult
 nsAlertsIconListener::ShowAlert(GdkPixbuf* aPixbuf)
 {
   mNotification = notify_notification_new(mAlertTitle.get(), mAlertText.get(),
                                           nullptr, nullptr);
@@ -196,19 +209,25 @@ nsAlertsIconListener::StartRequest(const
   NS_NewURI(getter_AddRefs(imageUri), aImageUrl);
   if (!imageUri)
     return ShowAlert(nullptr);
 
   nsCOMPtr<imgILoader> il(do_GetService("@mozilla.org/image/loader;1"));
   if (!il)
     return ShowAlert(nullptr);
 
-  return il->LoadImageXPCOM(imageUri, nullptr, nullptr, nullptr, nullptr,
-                            this, nullptr, nsIRequest::LOAD_NORMAL, nullptr,
-                            nullptr, getter_AddRefs(mIconRequest));
+  nsresult rv = il->LoadImageXPCOM(imageUri, nullptr, nullptr, nullptr, nullptr,
+                                   this, nullptr, nsIRequest::LOAD_NORMAL, nullptr,
+                                   nullptr, getter_AddRefs(mIconRequest));
+  if (NS_FAILED(rv))
+    return rv;
+
+  mIconRequest->StartDecoding();
+
+  return NS_OK;
 }
 
 void
 nsAlertsIconListener::SendCallback()
 {
   if (mAlertListener)
     mAlertListener->Observe(nullptr, "alertclickcallback", mAlertCookie.get());
 }