Browse Source

Load HICON directly in NotifyIcon

Cheng Zhao 9 years ago
parent
commit
9e26e5c121

+ 20 - 2
atom/browser/api/atom_api_tray.cc

@@ -26,7 +26,11 @@ namespace api {
 Tray::Tray(v8::Isolate* isolate, mate::Handle<NativeImage> image)
     : image_(isolate, image.ToV8()),
       tray_icon_(TrayIcon::Create()) {
+#if defined(OS_WIN)
+  tray_icon_->SetImage(image->GetHICON());
+#else
   tray_icon_->SetImage(image->image());
+#endif
   tray_icon_->AddObserver(this);
 }
 
@@ -99,13 +103,21 @@ void Tray::OnDragEnded() {
 
 void Tray::SetImage(v8::Isolate* isolate, mate::Handle<NativeImage> image) {
   image_.Reset(isolate, image.ToV8());
+#if defined(OS_WIN)
+  tray_icon_->SetImage(image->GetHICON());
+#else
   tray_icon_->SetImage(image->image());
+#endif
 }
 
 void Tray::SetPressedImage(v8::Isolate* isolate,
                            mate::Handle<NativeImage> image) {
   pressed_image_.Reset(isolate, image.ToV8());
+#if defined(OS_WIN)
+  tray_icon_->SetPressedImage(image->GetHICON());
+#else
   tray_icon_->SetPressedImage(image->image());
+#endif
 }
 
 void Tray::SetToolTip(const std::string& tool_tip) {
@@ -122,7 +134,7 @@ void Tray::SetHighlightMode(bool highlight) {
 
 void Tray::DisplayBalloon(mate::Arguments* args,
                           const mate::Dictionary& options) {
-  gfx::Image icon;
+  mate::Handle<NativeImage> icon;
   options.Get("icon", &icon);
   base::string16 title, content;
   if (!options.Get("title", &title) ||
@@ -131,7 +143,13 @@ void Tray::DisplayBalloon(mate::Arguments* args,
     return;
   }
 
-  tray_icon_->DisplayBalloon(icon, title, content);
+#if defined(OS_WIN)
+  tray_icon_->DisplayBalloon(
+      icon.IsEmpty() ? NULL : icon->GetHICON(), title, content);
+#else
+  tray_icon_->DisplayBalloon(
+      icon.IsEmpty() ? gfx::Image() : icon->image(), title, content);
+#endif
 }
 
 void Tray::PopUpContextMenu(mate::Arguments* args) {

+ 2 - 2
atom/browser/ui/tray_icon.cc

@@ -12,7 +12,7 @@ TrayIcon::TrayIcon() {
 TrayIcon::~TrayIcon() {
 }
 
-void TrayIcon::SetPressedImage(const gfx::Image& image) {
+void TrayIcon::SetPressedImage(ImageType image) {
 }
 
 void TrayIcon::SetTitle(const std::string& title) {
@@ -21,7 +21,7 @@ void TrayIcon::SetTitle(const std::string& title) {
 void TrayIcon::SetHighlightMode(bool highlight) {
 }
 
-void TrayIcon::DisplayBalloon(const gfx::Image& icon,
+void TrayIcon::DisplayBalloon(ImageType icon,
                               const base::string16& title,
                               const base::string16& contents) {
 }

+ 9 - 3
atom/browser/ui/tray_icon.h

@@ -19,13 +19,19 @@ class TrayIcon {
  public:
   static TrayIcon* Create();
 
+#if defined(OS_WIN)
+  using ImageType = HICON;
+#else
+  using ImageType = const gfx::Image&;
+#endif
+
   virtual ~TrayIcon();
 
   // Sets the image associated with this status icon.
-  virtual void SetImage(const gfx::Image& image) = 0;
+  virtual void SetImage(ImageType image) = 0;
 
   // Sets the image associated with this status icon when pressed.
-  virtual void SetPressedImage(const gfx::Image& image);
+  virtual void SetPressedImage(ImageType image);
 
   // Sets the hover text for this status icon. This is also used as the label
   // for the menu item which is created as a replacement for the status icon
@@ -43,7 +49,7 @@ class TrayIcon {
 
   // Displays a notification balloon with the specified contents.
   // Depending on the platform it might not appear by the icon tray.
-  virtual void DisplayBalloon(const gfx::Image& icon,
+  virtual void DisplayBalloon(ImageType icon,
                               const base::string16& title,
                               const base::string16& contents);
 

+ 9 - 14
atom/browser/ui/win/notify_icon.cc

@@ -9,7 +9,6 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/win/windows_version.h"
 #include "third_party/skia/include/core/SkBitmap.h"
-#include "ui/gfx/icon_util.h"
 #include "ui/gfx/image/image.h"
 #include "ui/gfx/geometry/point.h"
 #include "ui/gfx/geometry/rect.h"
@@ -26,6 +25,7 @@ NotifyIcon::NotifyIcon(NotifyIconHost* host,
       icon_id_(id),
       window_(window),
       message_id_(message),
+      icon_(NULL),
       menu_model_(NULL) {
   NOTIFYICONDATA icon_data;
   InitIconData(&icon_data);
@@ -80,7 +80,7 @@ void NotifyIcon::ResetIcon() {
   InitIconData(&icon_data);
   icon_data.uFlags |= NIF_MESSAGE;
   icon_data.uCallbackMessage = message_id_;
-  icon_data.hIcon = icon_.get();
+  icon_data.hIcon = icon_;
   // If we have an image, then set the NIF_ICON flag, which tells
   // Shell_NotifyIcon() to set the image for the status icon it creates.
   if (icon_data.hIcon)
@@ -91,19 +91,19 @@ void NotifyIcon::ResetIcon() {
     LOG(WARNING) << "Unable to re-create status tray icon.";
 }
 
-void NotifyIcon::SetImage(const gfx::Image& image) {
+void NotifyIcon::SetImage(HICON image) {
   // Create the icon.
+  icon_ = image;
   NOTIFYICONDATA icon_data;
   InitIconData(&icon_data);
   icon_data.uFlags |= NIF_ICON;
-  icon_ = IconUtil::CreateHICONFromSkBitmap(image.AsBitmap());
-  icon_data.hIcon = icon_.get();
+  icon_data.hIcon = image;
   BOOL result = Shell_NotifyIcon(NIM_MODIFY, &icon_data);
   if (!result)
     LOG(WARNING) << "Error setting status tray icon image";
 }
 
-void NotifyIcon::SetPressedImage(const gfx::Image& image) {
+void NotifyIcon::SetPressedImage(HICON image) {
   // Ignore pressed images, since the standard on Windows is to not highlight
   // pressed status icons.
 }
@@ -119,7 +119,7 @@ void NotifyIcon::SetToolTip(const std::string& tool_tip) {
     LOG(WARNING) << "Unable to set tooltip for status tray icon";
 }
 
-void NotifyIcon::DisplayBalloon(const gfx::Image& icon,
+void NotifyIcon::DisplayBalloon(HICON icon,
                                 const base::string16& title,
                                 const base::string16& contents) {
   NOTIFYICONDATA icon_data;
@@ -129,13 +129,8 @@ void NotifyIcon::DisplayBalloon(const gfx::Image& icon,
   wcsncpy_s(icon_data.szInfoTitle, title.c_str(), _TRUNCATE);
   wcsncpy_s(icon_data.szInfo, contents.c_str(), _TRUNCATE);
   icon_data.uTimeout = 0;
-
-  base::win::Version win_version = base::win::GetVersion();
-  if (!icon.IsEmpty() && win_version != base::win::VERSION_PRE_XP) {
-    balloon_icon_ = IconUtil::CreateHICONFromSkBitmap(icon.AsBitmap());
-    icon_data.hBalloonIcon = balloon_icon_.get();
-    icon_data.dwInfoFlags = NIIF_USER | NIIF_LARGE_ICON;
-  }
+  icon_data.hBalloonIcon = icon;
+  icon_data.dwInfoFlags = NIIF_USER | NIIF_LARGE_ICON;
 
   BOOL result = Shell_NotifyIcon(NIM_MODIFY, &icon_data);
   if (!result)

+ 4 - 8
atom/browser/ui/win/notify_icon.h

@@ -14,7 +14,6 @@
 #include "base/macros.h"
 #include "base/compiler_specific.h"
 #include "base/memory/scoped_ptr.h"
-#include "base/win/scoped_gdi_object.h"
 
 namespace gfx {
 class Point;
@@ -45,10 +44,10 @@ class NotifyIcon : public TrayIcon {
   UINT message_id() const { return message_id_; }
 
   // Overridden from TrayIcon:
-  void SetImage(const gfx::Image& image) override;
-  void SetPressedImage(const gfx::Image& image) override;
+  void SetImage(HICON image) override;
+  void SetPressedImage(HICON image) override;
   void SetToolTip(const std::string& tool_tip) override;
-  void DisplayBalloon(const gfx::Image& icon,
+  void DisplayBalloon(HICON icon,
                       const base::string16& title,
                       const base::string16& contents) override;
   void PopUpContextMenu(const gfx::Point& pos,
@@ -71,10 +70,7 @@ class NotifyIcon : public TrayIcon {
   UINT message_id_;
 
   // The currently-displayed icon for the window.
-  base::win::ScopedHICON icon_;
-
-  // The currently-displayed icon for the notification balloon.
-  base::win::ScopedHICON balloon_icon_;
+  HICON icon_;
 
   // The context menu.
   ui::SimpleMenuModel* menu_model_;

+ 15 - 5
atom/common/api/atom_api_native_image.cc

@@ -160,11 +160,10 @@ base::win::ScopedHICON ReadICOFromPath(const base::FilePath& path) {
                 LR_DEFAULTSIZE | LR_LOADFROMFILE)));
 }
 
-bool ReadImageSkiaFromICO(gfx::ImageSkia* image, HICON icon) {
+void ReadImageSkiaFromICO(gfx::ImageSkia* image, HICON icon) {
   // Convert the icon from the Windows specific HICON to gfx::ImageSkia.
-  scoped_ptr<SkBitmap> bitmap(IconUtil::  CreateSkBitmapFromHICON(icon));
+  scoped_ptr<SkBitmap> bitmap(IconUtil::CreateSkBitmapFromHICON(icon));
   image->AddRepresentation(gfx::ImageSkiaRep(*bitmap, 1.0f));
-  return true;
 }
 #endif
 
@@ -178,9 +177,9 @@ NativeImage::NativeImage(v8::Isolate* isolate, const gfx::Image& image)
 #if defined(OS_WIN)
 NativeImage::NativeImage(v8::Isolate* isolate, base::win::ScopedHICON&& hicon)
     : hicon_(std::move(hicon)) {
-  if (hicon.get()) {
+  if (hicon_.get()) {
     gfx::ImageSkia image_skia;
-    ReadImageSkiaFromICO(&image_skia, hicon.get());
+    ReadImageSkiaFromICO(&image_skia, hicon_.get());
     image_ = gfx::Image(image_skia);
   }
   Init(isolate);
@@ -189,6 +188,17 @@ NativeImage::NativeImage(v8::Isolate* isolate, base::win::ScopedHICON&& hicon)
 
 NativeImage::~NativeImage() {}
 
+#if defined(OS_WIN)
+HICON NativeImage::GetHICON() {
+  if (hicon_.get())
+    return hicon_.get();
+  if (image_.IsEmpty())
+    return NULL;
+  hicon_ = std::move(IconUtil::CreateHICONFromSkBitmap(image_.AsBitmap()));
+  return hicon_.get();
+}
+#endif
+
 v8::Local<v8::Value> NativeImage::ToPNG(v8::Isolate* isolate) {
   scoped_refptr<base::RefCountedMemory> png = image_.As1xPNGBytes();
   return node::Buffer::Copy(isolate,

+ 3 - 2
atom/common/api/atom_api_native_image.h

@@ -52,11 +52,12 @@ class NativeImage : public mate::Wrappable<NativeImage> {
   static void BuildPrototype(v8::Isolate* isolate,
                              v8::Local<v8::ObjectTemplate> prototype);
 
-  const gfx::Image& image() const { return image_; }
 #if defined(OS_WIN)
-  HICON hicon() const { return hicon_.get(); }
+  HICON GetHICON();
 #endif
 
+  const gfx::Image& image() const { return image_; }
+
  protected:
   NativeImage(v8::Isolate* isolate, const gfx::Image& image);
 #if defined(OS_WIN)