From 9e26e5c1210e97b5a83d3c1be219cf09cf839f39 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 20 May 2016 16:55:22 +0900 Subject: [PATCH] Load HICON directly in NotifyIcon --- atom/browser/api/atom_api_tray.cc | 22 ++++++++++++++++++++-- atom/browser/ui/tray_icon.cc | 4 ++-- atom/browser/ui/tray_icon.h | 12 +++++++++--- atom/browser/ui/win/notify_icon.cc | 23 +++++++++-------------- atom/browser/ui/win/notify_icon.h | 12 ++++-------- atom/common/api/atom_api_native_image.cc | 20 +++++++++++++++----- atom/common/api/atom_api_native_image.h | 5 +++-- 7 files changed, 62 insertions(+), 36 deletions(-) diff --git a/atom/browser/api/atom_api_tray.cc b/atom/browser/api/atom_api_tray.cc index 973bc83..edfc1d1 100644 --- a/atom/browser/api/atom_api_tray.cc +++ b/atom/browser/api/atom_api_tray.cc @@ -26,7 +26,11 @@ namespace api { Tray::Tray(v8::Isolate* isolate, mate::Handle 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 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 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 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) { diff --git a/atom/browser/ui/tray_icon.cc b/atom/browser/ui/tray_icon.cc index 60923c2..dcdb90a 100644 --- a/atom/browser/ui/tray_icon.cc +++ b/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) { } diff --git a/atom/browser/ui/tray_icon.h b/atom/browser/ui/tray_icon.h index c80ff08..dd01882 100644 --- a/atom/browser/ui/tray_icon.h +++ b/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); diff --git a/atom/browser/ui/win/notify_icon.cc b/atom/browser/ui/win/notify_icon.cc index 464dc14..98c967e 100644 --- a/atom/browser/ui/win/notify_icon.cc +++ b/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) diff --git a/atom/browser/ui/win/notify_icon.h b/atom/browser/ui/win/notify_icon.h index 53ed49b..1c6f240 100644 --- a/atom/browser/ui/win/notify_icon.h +++ b/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_; diff --git a/atom/common/api/atom_api_native_image.cc b/atom/common/api/atom_api_native_image.cc index 1b1b7ac..92fba4b 100644 --- a/atom/common/api/atom_api_native_image.cc +++ b/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 bitmap(IconUtil:: CreateSkBitmapFromHICON(icon)); + scoped_ptr 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 NativeImage::ToPNG(v8::Isolate* isolate) { scoped_refptr png = image_.As1xPNGBytes(); return node::Buffer::Copy(isolate, diff --git a/atom/common/api/atom_api_native_image.h b/atom/common/api/atom_api_native_image.h index faf00f3..f79654d 100644 --- a/atom/common/api/atom_api_native_image.h +++ b/atom/common/api/atom_api_native_image.h @@ -52,11 +52,12 @@ class NativeImage : public mate::Wrappable { static void BuildPrototype(v8::Isolate* isolate, v8::Local 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) -- 2.7.4