feat: allow GUID parameter to avoid systray demotion on Windows (#21891)
* fix: systray icon demotion Adding support for GUID parameter in Tray API. In combination with signed binaries this allows to maintain the position in the systray on Windows. * unit tests * make mac and linux compile
This commit is contained in:
parent
2955c67c4e
commit
89eb309d0b
13 changed files with 143 additions and 15 deletions
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "shell/browser/ui/win/notify_icon.h"
|
||||
|
||||
#include <objbase.h>
|
||||
#include <utility>
|
||||
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
|
@ -43,12 +44,18 @@ UINT ConvertIconType(electron::TrayIcon::IconType type) {
|
|||
|
||||
namespace electron {
|
||||
|
||||
NotifyIcon::NotifyIcon(NotifyIconHost* host, UINT id, HWND window, UINT message)
|
||||
NotifyIcon::NotifyIcon(NotifyIconHost* host,
|
||||
UINT id,
|
||||
HWND window,
|
||||
UINT message,
|
||||
GUID guid)
|
||||
: host_(host),
|
||||
icon_id_(id),
|
||||
window_(window),
|
||||
message_id_(message),
|
||||
weak_factory_(this) {
|
||||
guid_ = guid;
|
||||
is_using_guid_ = guid != GUID_DEFAULT;
|
||||
NOTIFYICONDATA icon_data;
|
||||
InitIconData(&icon_data);
|
||||
icon_data.uFlags |= NIF_MESSAGE;
|
||||
|
@ -246,6 +253,9 @@ gfx::Rect NotifyIcon::GetBounds() {
|
|||
icon_id.uID = icon_id_;
|
||||
icon_id.hWnd = window_;
|
||||
icon_id.cbSize = sizeof(NOTIFYICONIDENTIFIER);
|
||||
if (is_using_guid_) {
|
||||
icon_id.guidItem = guid_;
|
||||
}
|
||||
|
||||
RECT rect = {0};
|
||||
Shell_NotifyIconGetRect(&icon_id, &rect);
|
||||
|
@ -257,6 +267,10 @@ void NotifyIcon::InitIconData(NOTIFYICONDATA* icon_data) {
|
|||
icon_data->cbSize = sizeof(NOTIFYICONDATA);
|
||||
icon_data->hWnd = window_;
|
||||
icon_data->uID = icon_id_;
|
||||
if (is_using_guid_) {
|
||||
icon_data->uFlags = NIF_GUID;
|
||||
icon_data->guidItem = guid_;
|
||||
}
|
||||
}
|
||||
|
||||
void NotifyIcon::OnContextMenuClosed() {
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "base/memory/weak_ptr.h"
|
||||
#include "base/win/scoped_gdi_object.h"
|
||||
#include "shell/browser/ui/tray_icon.h"
|
||||
#include "shell/browser/ui/win/notify_icon_host.h"
|
||||
|
||||
namespace gfx {
|
||||
class Point;
|
||||
|
@ -34,7 +35,11 @@ class NotifyIconHost;
|
|||
class NotifyIcon : public TrayIcon {
|
||||
public:
|
||||
// Constructor which provides this icon's unique ID and messaging window.
|
||||
NotifyIcon(NotifyIconHost* host, UINT id, HWND window, UINT message);
|
||||
NotifyIcon(NotifyIconHost* host,
|
||||
UINT id,
|
||||
HWND window,
|
||||
UINT message,
|
||||
GUID guid);
|
||||
~NotifyIcon() override;
|
||||
|
||||
// Handles a click event from the user - if |left_button_click| is true and
|
||||
|
@ -53,6 +58,7 @@ class NotifyIcon : public TrayIcon {
|
|||
UINT icon_id() const { return icon_id_; }
|
||||
HWND window() const { return window_; }
|
||||
UINT message_id() const { return message_id_; }
|
||||
GUID guid() const { return guid_; }
|
||||
|
||||
// Overridden from TrayIcon:
|
||||
void SetImage(HICON image) override;
|
||||
|
@ -89,6 +95,12 @@ class NotifyIcon : public TrayIcon {
|
|||
// The context menu.
|
||||
AtomMenuModel* menu_model_ = nullptr;
|
||||
|
||||
// An optional GUID used for identifying tray entries on Windows
|
||||
GUID guid_ = GUID_DEFAULT;
|
||||
|
||||
// indicates whether the tray entry is associated with a guid
|
||||
bool is_using_guid_ = false;
|
||||
|
||||
// Context menu associated with this icon (if any).
|
||||
std::unique_ptr<views::MenuRunner> menu_runner_;
|
||||
|
||||
|
|
|
@ -83,9 +83,22 @@ NotifyIconHost::~NotifyIconHost() {
|
|||
delete ptr;
|
||||
}
|
||||
|
||||
NotifyIcon* NotifyIconHost::CreateNotifyIcon() {
|
||||
NotifyIcon* NotifyIconHost::CreateNotifyIcon(base::Optional<UUID> guid) {
|
||||
if (guid.has_value()) {
|
||||
for (NotifyIcons::const_iterator i(notify_icons_.begin());
|
||||
i != notify_icons_.end(); ++i) {
|
||||
NotifyIcon* current_win_icon = static_cast<NotifyIcon*>(*i);
|
||||
if (current_win_icon->guid() == guid.value()) {
|
||||
LOG(WARNING)
|
||||
<< "Guid already in use. Existing tray entry will be replaced.";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NotifyIcon* notify_icon =
|
||||
new NotifyIcon(this, NextIconId(), window_, kNotifyIconMessage);
|
||||
new NotifyIcon(this, NextIconId(), window_, kNotifyIconMessage,
|
||||
guid.has_value() ? guid.value() : GUID_DEFAULT);
|
||||
|
||||
notify_icons_.push_back(notify_icon);
|
||||
return notify_icon;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,10 @@
|
|||
#include <vector>
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "base/optional.h"
|
||||
#include "shell/common/gin_converters/guid_converter.h"
|
||||
|
||||
const GUID GUID_DEFAULT = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
|
||||
|
||||
namespace electron {
|
||||
|
||||
|
@ -20,7 +24,7 @@ class NotifyIconHost {
|
|||
NotifyIconHost();
|
||||
~NotifyIconHost();
|
||||
|
||||
NotifyIcon* CreateNotifyIcon();
|
||||
NotifyIcon* CreateNotifyIcon(base::Optional<UUID> guid);
|
||||
void Remove(NotifyIcon* notify_icon);
|
||||
|
||||
private:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue