Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add new options to tray.displayBalloon() #19544

Merged
merged 1 commit into from Aug 8, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 9 additions & 1 deletion docs/api/tray.md
Expand Up @@ -222,12 +222,20 @@ Returns `Boolean` - Whether double click events will be ignored.
#### `tray.displayBalloon(options)` _Windows_

* `options` Object
* `icon` ([NativeImage](native-image.md) | String) (optional) -
* `icon` ([NativeImage](native-image.md) | String) (optional) - Icon to use when `iconType` is `custom`.
* `iconType` String (optional) - Can be `none`, `info`, `warning`, `error` or `custom`. Default is `custom`.
* `title` String
* `content` String
* `largeIcon` Boolean (optional) - The large version of the icon should be used. Default is `true`. Maps to [`NIIF_LARGE_ICON`][NIIF_LARGE_ICON].
* `noSound` Boolean (optional) - Do not play the associated sound. Default is `false`. Maps to [`NIIF_NOSOUND`][NIIF_NOSOUND].
* `respectQuietTime` Boolean (optional) - Do not display the balloon notification if the current user is in "quiet time". Default is `false`. Maps to [`NIIF_RESPECT_QUIET_TIME`][NIIF_RESPECT_QUIET_TIME].

Displays a tray balloon.

[NIIF_NOSOUND]: https://docs.microsoft.com/en-us/windows/win32/api/shellapi/ns-shellapi-notifyicondataa#niif_nosound-0x00000010
[NIIF_LARGE_ICON]: https://docs.microsoft.com/en-us/windows/win32/api/shellapi/ns-shellapi-notifyicondataa#niif_large_icon-0x00000020
[NIIF_RESPECT_QUIET_TIME]: https://docs.microsoft.com/en-us/windows/win32/api/shellapi/ns-shellapi-notifyicondataa#niif_respect_quiet_time-0x00000080

#### `tray.removeBalloon()` _Windows_

Removes a tray balloon.
Expand Down
60 changes: 51 additions & 9 deletions shell/browser/api/atom_api_tray.cc
Expand Up @@ -18,6 +18,39 @@
#include "shell/common/node_includes.h"
#include "ui/gfx/image/image.h"

namespace mate {

template <>
struct Converter<electron::TrayIcon::IconType> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
electron::TrayIcon::IconType* out) {
using IconType = electron::TrayIcon::IconType;
std::string mode;
if (ConvertFromV8(isolate, val, &mode)) {
if (mode == "none") {
*out = IconType::None;
return true;
} else if (mode == "info") {
*out = IconType::Info;
return true;
} else if (mode == "warning") {
*out = IconType::Warning;
return true;
} else if (mode == "error") {
*out = IconType::Error;
return true;
} else if (mode == "custom") {
*out = IconType::Custom;
return true;
}
}
return false;
}
};

} // namespace mate

namespace electron {

namespace api {
Expand Down Expand Up @@ -157,22 +190,31 @@ bool Tray::GetIgnoreDoubleClickEvents() {

void Tray::DisplayBalloon(mate::Arguments* args,
const mate::Dictionary& options) {
mate::Handle<NativeImage> icon;
options.Get("icon", &icon);
base::string16 title, content;
if (!options.Get("title", &title) || !options.Get("content", &content)) {
TrayIcon::BalloonOptions balloon_options;

if (!options.Get("title", &balloon_options.title) ||
!options.Get("content", &balloon_options.content)) {
args->ThrowError("'title' and 'content' must be defined");
return;
}

mate::Handle<NativeImage> icon;
options.Get("icon", &icon);
options.Get("iconType", &balloon_options.icon_type);
options.Get("largeIcon", &balloon_options.large_icon);
options.Get("noSound", &balloon_options.no_sound);
options.Get("respectQuietTime", &balloon_options.respect_quiet_time);

if (!icon.IsEmpty()) {
#if defined(OS_WIN)
tray_icon_->DisplayBalloon(
icon.IsEmpty() ? NULL : icon->GetHICON(GetSystemMetrics(SM_CXICON)),
title, content);
balloon_options.icon = icon->GetHICON(
GetSystemMetrics(balloon_options.large_icon ? SM_CXICON : SM_CXSMICON));
#else
tray_icon_->DisplayBalloon(icon.IsEmpty() ? gfx::Image() : icon->image(),
title, content);
balloon_options.icon = icon->image();
#endif
}

tray_icon_->DisplayBalloon(balloon_options);
}

void Tray::RemoveBalloon() {
Expand Down
6 changes: 3 additions & 3 deletions shell/browser/ui/tray_icon.cc
Expand Up @@ -6,15 +6,15 @@

namespace electron {

TrayIcon::BalloonOptions::BalloonOptions() = default;

TrayIcon::TrayIcon() {}

TrayIcon::~TrayIcon() {}

void TrayIcon::SetPressedImage(ImageType image) {}

void TrayIcon::DisplayBalloon(ImageType icon,
const base::string16& title,
const base::string16& contents) {}
void TrayIcon::DisplayBalloon(const BalloonOptions& options) {}

void TrayIcon::RemoveBalloon() {}

Expand Down
22 changes: 19 additions & 3 deletions shell/browser/ui/tray_icon.h
Expand Up @@ -49,11 +49,27 @@ class TrayIcon {
virtual std::string GetTitle() = 0;
#endif

enum class IconType { None, Info, Warning, Error, Custom };

struct BalloonOptions {
IconType icon_type = IconType::Custom;
#if defined(OS_WIN)
HICON icon = nullptr;
#else
gfx::Image icon;
#endif
base::string16 title;
base::string16 content;
bool large_icon = true;
bool no_sound = false;
bool respect_quiet_time = false;

BalloonOptions();
};

// Displays a notification balloon with the specified contents.
// Depending on the platform it might not appear by the icon tray.
virtual void DisplayBalloon(ImageType icon,
const base::string16& title,
const base::string16& contents);
virtual void DisplayBalloon(const BalloonOptions& options);

// Removes the notification balloon.
virtual void RemoveBalloon();
Expand Down
44 changes: 36 additions & 8 deletions shell/browser/ui/win/notify_icon.cc
Expand Up @@ -17,6 +17,28 @@
#include "ui/views/controls/menu/menu_runner.h"
#include "ui/views/widget/widget.h"

namespace {

UINT ConvertIconType(electron::TrayIcon::IconType type) {
using IconType = electron::TrayIcon::IconType;
switch (type) {
case IconType::None:
return NIIF_NONE;
case IconType::Info:
return NIIF_INFO;
case IconType::Warning:
return NIIF_WARNING;
case IconType::Error:
return NIIF_ERROR;
case IconType::Custom:
return NIIF_USER;
default:
NOTREACHED() << "Invalid icon type";
}
}

} // namespace

namespace electron {

NotifyIcon::NotifyIcon(NotifyIconHost* host, UINT id, HWND window, UINT message)
Expand Down Expand Up @@ -120,18 +142,24 @@ void NotifyIcon::SetToolTip(const std::string& tool_tip) {
LOG(WARNING) << "Unable to set tooltip for status tray icon";
}

void NotifyIcon::DisplayBalloon(HICON icon,
const base::string16& title,
const base::string16& contents) {
void NotifyIcon::DisplayBalloon(const BalloonOptions& options) {
NOTIFYICONDATA icon_data;
InitIconData(&icon_data);
icon_data.uFlags |= NIF_INFO;
icon_data.dwInfoFlags = NIIF_INFO;
wcsncpy_s(icon_data.szInfoTitle, title.c_str(), _TRUNCATE);
wcsncpy_s(icon_data.szInfo, contents.c_str(), _TRUNCATE);
wcsncpy_s(icon_data.szInfoTitle, options.title.c_str(), _TRUNCATE);
wcsncpy_s(icon_data.szInfo, options.content.c_str(), _TRUNCATE);
icon_data.uTimeout = 0;
icon_data.hBalloonIcon = icon;
icon_data.dwInfoFlags = NIIF_USER | NIIF_LARGE_ICON;
icon_data.hBalloonIcon = options.icon;
icon_data.dwInfoFlags = ConvertIconType(options.icon_type);

if (options.large_icon)
icon_data.dwInfoFlags |= NIIF_LARGE_ICON;

if (options.no_sound)
icon_data.dwInfoFlags |= NIIF_NOSOUND;

if (options.respect_quiet_time)
icon_data.dwInfoFlags |= NIIF_RESPECT_QUIET_TIME;

BOOL result = Shell_NotifyIcon(NIM_MODIFY, &icon_data);
if (!result)
Expand Down
4 changes: 1 addition & 3 deletions shell/browser/ui/win/notify_icon.h
Expand Up @@ -58,9 +58,7 @@ class NotifyIcon : public TrayIcon {
void SetImage(HICON image) override;
void SetPressedImage(HICON image) override;
void SetToolTip(const std::string& tool_tip) override;
void DisplayBalloon(HICON icon,
const base::string16& title,
const base::string16& contents) override;
void DisplayBalloon(const BalloonOptions& options) override;
void RemoveBalloon() override;
void PopUpContextMenu(const gfx::Point& pos,
AtomMenuModel* menu_model) override;
Expand Down