feat: add new options to tray.displayBalloon() (#19544)
This commit is contained in:
parent
58840f39bb
commit
0fb3c8cb7c
6 changed files with 119 additions and 27 deletions
|
@ -222,12 +222,20 @@ Returns `Boolean` - Whether double click events will be ignored.
|
||||||
#### `tray.displayBalloon(options)` _Windows_
|
#### `tray.displayBalloon(options)` _Windows_
|
||||||
|
|
||||||
* `options` Object
|
* `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
|
* `title` String
|
||||||
* `content` 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.
|
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_
|
#### `tray.removeBalloon()` _Windows_
|
||||||
|
|
||||||
Removes a tray balloon.
|
Removes a tray balloon.
|
||||||
|
|
|
@ -18,6 +18,39 @@
|
||||||
#include "shell/common/node_includes.h"
|
#include "shell/common/node_includes.h"
|
||||||
#include "ui/gfx/image/image.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 electron {
|
||||||
|
|
||||||
namespace api {
|
namespace api {
|
||||||
|
@ -157,22 +190,31 @@ bool Tray::GetIgnoreDoubleClickEvents() {
|
||||||
|
|
||||||
void Tray::DisplayBalloon(mate::Arguments* args,
|
void Tray::DisplayBalloon(mate::Arguments* args,
|
||||||
const mate::Dictionary& options) {
|
const mate::Dictionary& options) {
|
||||||
mate::Handle<NativeImage> icon;
|
TrayIcon::BalloonOptions balloon_options;
|
||||||
options.Get("icon", &icon);
|
|
||||||
base::string16 title, content;
|
if (!options.Get("title", &balloon_options.title) ||
|
||||||
if (!options.Get("title", &title) || !options.Get("content", &content)) {
|
!options.Get("content", &balloon_options.content)) {
|
||||||
args->ThrowError("'title' and 'content' must be defined");
|
args->ThrowError("'title' and 'content' must be defined");
|
||||||
return;
|
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)
|
#if defined(OS_WIN)
|
||||||
tray_icon_->DisplayBalloon(
|
balloon_options.icon = icon->GetHICON(
|
||||||
icon.IsEmpty() ? NULL : icon->GetHICON(GetSystemMetrics(SM_CXICON)),
|
GetSystemMetrics(balloon_options.large_icon ? SM_CXICON : SM_CXSMICON));
|
||||||
title, content);
|
|
||||||
#else
|
#else
|
||||||
tray_icon_->DisplayBalloon(icon.IsEmpty() ? gfx::Image() : icon->image(),
|
balloon_options.icon = icon->image();
|
||||||
title, content);
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
tray_icon_->DisplayBalloon(balloon_options);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tray::RemoveBalloon() {
|
void Tray::RemoveBalloon() {
|
||||||
|
|
|
@ -6,15 +6,15 @@
|
||||||
|
|
||||||
namespace electron {
|
namespace electron {
|
||||||
|
|
||||||
|
TrayIcon::BalloonOptions::BalloonOptions() = default;
|
||||||
|
|
||||||
TrayIcon::TrayIcon() {}
|
TrayIcon::TrayIcon() {}
|
||||||
|
|
||||||
TrayIcon::~TrayIcon() {}
|
TrayIcon::~TrayIcon() {}
|
||||||
|
|
||||||
void TrayIcon::SetPressedImage(ImageType image) {}
|
void TrayIcon::SetPressedImage(ImageType image) {}
|
||||||
|
|
||||||
void TrayIcon::DisplayBalloon(ImageType icon,
|
void TrayIcon::DisplayBalloon(const BalloonOptions& options) {}
|
||||||
const base::string16& title,
|
|
||||||
const base::string16& contents) {}
|
|
||||||
|
|
||||||
void TrayIcon::RemoveBalloon() {}
|
void TrayIcon::RemoveBalloon() {}
|
||||||
|
|
||||||
|
|
|
@ -49,11 +49,27 @@ class TrayIcon {
|
||||||
virtual std::string GetTitle() = 0;
|
virtual std::string GetTitle() = 0;
|
||||||
#endif
|
#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.
|
// Displays a notification balloon with the specified contents.
|
||||||
// Depending on the platform it might not appear by the icon tray.
|
// Depending on the platform it might not appear by the icon tray.
|
||||||
virtual void DisplayBalloon(ImageType icon,
|
virtual void DisplayBalloon(const BalloonOptions& options);
|
||||||
const base::string16& title,
|
|
||||||
const base::string16& contents);
|
|
||||||
|
|
||||||
// Removes the notification balloon.
|
// Removes the notification balloon.
|
||||||
virtual void RemoveBalloon();
|
virtual void RemoveBalloon();
|
||||||
|
|
|
@ -17,6 +17,28 @@
|
||||||
#include "ui/views/controls/menu/menu_runner.h"
|
#include "ui/views/controls/menu/menu_runner.h"
|
||||||
#include "ui/views/widget/widget.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 {
|
namespace electron {
|
||||||
|
|
||||||
NotifyIcon::NotifyIcon(NotifyIconHost* host, UINT id, HWND window, UINT message)
|
NotifyIcon::NotifyIcon(NotifyIconHost* host, UINT id, HWND window, UINT message)
|
||||||
|
@ -120,18 +142,24 @@ void NotifyIcon::SetToolTip(const std::string& tool_tip) {
|
||||||
LOG(WARNING) << "Unable to set tooltip for status tray icon";
|
LOG(WARNING) << "Unable to set tooltip for status tray icon";
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotifyIcon::DisplayBalloon(HICON icon,
|
void NotifyIcon::DisplayBalloon(const BalloonOptions& options) {
|
||||||
const base::string16& title,
|
|
||||||
const base::string16& contents) {
|
|
||||||
NOTIFYICONDATA icon_data;
|
NOTIFYICONDATA icon_data;
|
||||||
InitIconData(&icon_data);
|
InitIconData(&icon_data);
|
||||||
icon_data.uFlags |= NIF_INFO;
|
icon_data.uFlags |= NIF_INFO;
|
||||||
icon_data.dwInfoFlags = NIIF_INFO;
|
wcsncpy_s(icon_data.szInfoTitle, options.title.c_str(), _TRUNCATE);
|
||||||
wcsncpy_s(icon_data.szInfoTitle, title.c_str(), _TRUNCATE);
|
wcsncpy_s(icon_data.szInfo, options.content.c_str(), _TRUNCATE);
|
||||||
wcsncpy_s(icon_data.szInfo, contents.c_str(), _TRUNCATE);
|
|
||||||
icon_data.uTimeout = 0;
|
icon_data.uTimeout = 0;
|
||||||
icon_data.hBalloonIcon = icon;
|
icon_data.hBalloonIcon = options.icon;
|
||||||
icon_data.dwInfoFlags = NIIF_USER | NIIF_LARGE_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);
|
BOOL result = Shell_NotifyIcon(NIM_MODIFY, &icon_data);
|
||||||
if (!result)
|
if (!result)
|
||||||
|
|
|
@ -58,9 +58,7 @@ class NotifyIcon : public TrayIcon {
|
||||||
void SetImage(HICON image) override;
|
void SetImage(HICON image) override;
|
||||||
void SetPressedImage(HICON image) override;
|
void SetPressedImage(HICON image) override;
|
||||||
void SetToolTip(const std::string& tool_tip) override;
|
void SetToolTip(const std::string& tool_tip) override;
|
||||||
void DisplayBalloon(HICON icon,
|
void DisplayBalloon(const BalloonOptions& options) override;
|
||||||
const base::string16& title,
|
|
||||||
const base::string16& contents) override;
|
|
||||||
void RemoveBalloon() override;
|
void RemoveBalloon() override;
|
||||||
void PopUpContextMenu(const gfx::Point& pos,
|
void PopUpContextMenu(const gfx::Point& pos,
|
||||||
AtomMenuModel* menu_model) override;
|
AtomMenuModel* menu_model) override;
|
||||||
|
|
Loading…
Reference in a new issue