fix: fallback to GtkStatusIcon when app indicator is not supported (#36815)
* chore: get ready for multi backend tray * fix: fallback to GtkStatusIcon when app indicator is not supported * chore: use smart pointers
This commit is contained in:
parent
7d46d3ec9d
commit
c303135b02
10 changed files with 377 additions and 111 deletions
2
BUILD.gn
2
BUILD.gn
|
@ -632,8 +632,6 @@ source_set("electron_lib") {
|
||||||
sources += [
|
sources += [
|
||||||
"shell/browser/certificate_manager_model.cc",
|
"shell/browser/certificate_manager_model.cc",
|
||||||
"shell/browser/certificate_manager_model.h",
|
"shell/browser/certificate_manager_model.h",
|
||||||
"shell/browser/ui/gtk/menu_util.cc",
|
|
||||||
"shell/browser/ui/gtk/menu_util.h",
|
|
||||||
"shell/browser/ui/gtk_util.cc",
|
"shell/browser/ui/gtk_util.cc",
|
||||||
"shell/browser/ui/gtk_util.h",
|
"shell/browser/ui/gtk_util.h",
|
||||||
]
|
]
|
||||||
|
|
|
@ -29,8 +29,9 @@ __Platform Considerations__
|
||||||
|
|
||||||
__Linux__
|
__Linux__
|
||||||
|
|
||||||
* Tray icon requires support of [StatusNotifierItem](https://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/)
|
* Tray icon uses [StatusNotifierItem](https://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/)
|
||||||
in user's desktop environment.
|
by default, when it is not available in user's desktop environment the
|
||||||
|
`GtkStatusIcon` will be used instead.
|
||||||
* The `click` event is emitted when the tray icon receives activation from
|
* The `click` event is emitted when the tray icon receives activation from
|
||||||
user, however the StatusNotifierItem spec does not specify which action would
|
user, however the StatusNotifierItem spec does not specify which action would
|
||||||
cause an activation, for some environments it is left mouse click, but for
|
cause an activation, for some environments it is left mouse click, but for
|
||||||
|
|
|
@ -35,9 +35,15 @@ filenames = {
|
||||||
"shell/browser/relauncher_linux.cc",
|
"shell/browser/relauncher_linux.cc",
|
||||||
"shell/browser/ui/electron_desktop_window_tree_host_linux.cc",
|
"shell/browser/ui/electron_desktop_window_tree_host_linux.cc",
|
||||||
"shell/browser/ui/file_dialog_gtk.cc",
|
"shell/browser/ui/file_dialog_gtk.cc",
|
||||||
|
"shell/browser/ui/gtk/menu_gtk.cc",
|
||||||
|
"shell/browser/ui/gtk/menu_gtk.h",
|
||||||
|
"shell/browser/ui/gtk/menu_util.cc",
|
||||||
|
"shell/browser/ui/gtk/menu_util.h",
|
||||||
"shell/browser/ui/message_box_gtk.cc",
|
"shell/browser/ui/message_box_gtk.cc",
|
||||||
"shell/browser/ui/tray_icon_gtk.cc",
|
"shell/browser/ui/status_icon_gtk.cc",
|
||||||
"shell/browser/ui/tray_icon_gtk.h",
|
"shell/browser/ui/status_icon_gtk.h",
|
||||||
|
"shell/browser/ui/tray_icon_linux.cc",
|
||||||
|
"shell/browser/ui/tray_icon_linux.h",
|
||||||
"shell/browser/ui/views/client_frame_view_linux.cc",
|
"shell/browser/ui/views/client_frame_view_linux.cc",
|
||||||
"shell/browser/ui/views/client_frame_view_linux.h",
|
"shell/browser/ui/views/client_frame_view_linux.h",
|
||||||
"shell/common/application_info_linux.cc",
|
"shell/common/application_info_linux.cc",
|
||||||
|
|
70
shell/browser/ui/gtk/menu_gtk.cc
Normal file
70
shell/browser/ui/gtk/menu_gtk.cc
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
// Copyright 2014 The Chromium Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#include "shell/browser/ui/gtk/menu_gtk.h"
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
#include "shell/browser/ui/gtk/menu_util.h"
|
||||||
|
#include "ui/base/models/menu_model.h"
|
||||||
|
|
||||||
|
namespace electron {
|
||||||
|
|
||||||
|
namespace gtkui {
|
||||||
|
|
||||||
|
MenuGtk::MenuGtk(ui::MenuModel* model)
|
||||||
|
: menu_model_(model), gtk_menu_(TakeGObject(gtk_menu_new())) {
|
||||||
|
if (menu_model_) {
|
||||||
|
BuildSubmenuFromModel(menu_model_, gtk_menu_,
|
||||||
|
G_CALLBACK(OnMenuItemActivatedThunk),
|
||||||
|
&block_activation_, this);
|
||||||
|
Refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MenuGtk::~MenuGtk() {
|
||||||
|
gtk_widget_destroy(gtk_menu_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MenuGtk::Refresh() {
|
||||||
|
gtk_container_foreach(GTK_CONTAINER(gtk_menu_.get()), SetMenuItemInfo,
|
||||||
|
&block_activation_);
|
||||||
|
}
|
||||||
|
|
||||||
|
GtkMenu* MenuGtk::GetGtkMenu() {
|
||||||
|
return GTK_MENU(gtk_menu_.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
void MenuGtk::OnMenuItemActivated(GtkWidget* menu_item) {
|
||||||
|
if (block_activation_)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ui::MenuModel* model = ModelForMenuItem(GTK_MENU_ITEM(menu_item));
|
||||||
|
if (!model) {
|
||||||
|
// There won't be a model for "native" submenus like the "Input Methods"
|
||||||
|
// context menu. We don't need to handle activation messages for submenus
|
||||||
|
// anyway, so we can just return here.
|
||||||
|
DCHECK(gtk_menu_item_get_submenu(GTK_MENU_ITEM(menu_item)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The activate signal is sent to radio items as they get deselected;
|
||||||
|
// ignore it in this case.
|
||||||
|
if (GTK_IS_RADIO_MENU_ITEM(menu_item) &&
|
||||||
|
!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_item))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int id;
|
||||||
|
if (!GetMenuItemID(menu_item, &id))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// The menu item can still be activated by hotkeys even if it is disabled.
|
||||||
|
if (model->IsEnabledAt(id))
|
||||||
|
ExecuteCommand(model, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace gtkui
|
||||||
|
|
||||||
|
} // namespace electron
|
48
shell/browser/ui/gtk/menu_gtk.h
Normal file
48
shell/browser/ui/gtk/menu_gtk.h
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
// Copyright 2014 The Chromium Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#ifndef ELECTRON_SHELL_BROWSER_UI_GTK_MENU_GTK_H_
|
||||||
|
#define ELECTRON_SHELL_BROWSER_UI_GTK_MENU_GTK_H_
|
||||||
|
|
||||||
|
#include "base/callback.h"
|
||||||
|
#include "base/memory/raw_ptr.h"
|
||||||
|
#include "ui/base/glib/glib_signal.h"
|
||||||
|
#include "ui/base/glib/scoped_gobject.h"
|
||||||
|
|
||||||
|
typedef struct _GtkMenu GtkMenu;
|
||||||
|
typedef struct _GtkWidget GtkWidget;
|
||||||
|
|
||||||
|
namespace ui {
|
||||||
|
class MenuModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace electron {
|
||||||
|
|
||||||
|
namespace gtkui {
|
||||||
|
|
||||||
|
class MenuGtk {
|
||||||
|
public:
|
||||||
|
explicit MenuGtk(ui::MenuModel* model);
|
||||||
|
virtual ~MenuGtk();
|
||||||
|
|
||||||
|
// Refreshes all the menu item labels and menu item checked/enabled states.
|
||||||
|
void Refresh();
|
||||||
|
|
||||||
|
GtkMenu* GetGtkMenu();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Callback for when a menu item is activated.
|
||||||
|
CHROMEG_CALLBACK_0(MenuGtk, void, OnMenuItemActivated, GtkWidget*);
|
||||||
|
|
||||||
|
raw_ptr<ui::MenuModel> menu_model_; // not owned
|
||||||
|
ScopedGObject<GtkWidget> gtk_menu_;
|
||||||
|
|
||||||
|
bool block_activation_ = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace gtkui
|
||||||
|
|
||||||
|
} // namespace electron
|
||||||
|
|
||||||
|
#endif // ELECTRON_SHELL_BROWSER_UI_GTK_MENU_GTK_H_
|
68
shell/browser/ui/status_icon_gtk.cc
Normal file
68
shell/browser/ui/status_icon_gtk.cc
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
// Copyright (c) 2023 Microsoft, Inc.
|
||||||
|
// Copyright (c) 2011 The Chromium Authors.
|
||||||
|
// Use of this source code is governed by the MIT license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#include "shell/browser/ui/status_icon_gtk.h"
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
#include "base/strings/utf_string_conversions.h"
|
||||||
|
#include "shell/browser/ui/gtk/menu_gtk.h"
|
||||||
|
#include "shell/browser/ui/gtk_util.h"
|
||||||
|
#include "ui/gfx/image/image_skia.h"
|
||||||
|
|
||||||
|
namespace electron {
|
||||||
|
|
||||||
|
StatusIconGtk::StatusIconGtk() : icon_(TakeGObject(gtk_status_icon_new())) {
|
||||||
|
g_signal_connect(icon_, "activate", G_CALLBACK(OnClickThunk), this);
|
||||||
|
g_signal_connect(icon_, "popup_menu", G_CALLBACK(OnContextMenuRequestedThunk),
|
||||||
|
this);
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusIconGtk::~StatusIconGtk() = default;
|
||||||
|
|
||||||
|
void StatusIconGtk::SetIcon(const gfx::ImageSkia& image) {
|
||||||
|
if (image.isNull())
|
||||||
|
return;
|
||||||
|
|
||||||
|
GdkPixbuf* pixbuf = gtk_util::GdkPixbufFromSkBitmap(*image.bitmap());
|
||||||
|
gtk_status_icon_set_from_pixbuf(icon_, pixbuf);
|
||||||
|
g_object_unref(pixbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StatusIconGtk::SetToolTip(const std::u16string& tool_tip) {
|
||||||
|
gtk_status_icon_set_tooltip_text(icon_, base::UTF16ToUTF8(tool_tip).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void StatusIconGtk::UpdatePlatformContextMenu(ui::MenuModel* model) {
|
||||||
|
if (model)
|
||||||
|
menu_ = std::make_unique<gtkui::MenuGtk>(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StatusIconGtk::RefreshPlatformContextMenu() {
|
||||||
|
if (menu_)
|
||||||
|
menu_->Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StatusIconGtk::OnSetDelegate() {
|
||||||
|
SetIcon(delegate_->GetImage());
|
||||||
|
SetToolTip(delegate_->GetToolTip());
|
||||||
|
UpdatePlatformContextMenu(delegate_->GetMenuModel());
|
||||||
|
gtk_status_icon_set_visible(icon_, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StatusIconGtk::OnClick(GtkStatusIcon* status_icon) {
|
||||||
|
delegate_->OnClick();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StatusIconGtk::OnContextMenuRequested(GtkStatusIcon* status_icon,
|
||||||
|
guint button,
|
||||||
|
guint32 activate_time) {
|
||||||
|
if (menu_.get()) {
|
||||||
|
gtk_menu_popup(menu_->GetGtkMenu(), nullptr, nullptr,
|
||||||
|
gtk_status_icon_position_menu, icon_, button, activate_time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace electron
|
52
shell/browser/ui/status_icon_gtk.h
Normal file
52
shell/browser/ui/status_icon_gtk.h
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
// Copyright (c) 2023 Microsoft, Inc.
|
||||||
|
// Use of this source code is governed by the MIT license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#ifndef ELECTRON_SHELL_BROWSER_UI_STATUS_ICON_GTK_H_
|
||||||
|
#define ELECTRON_SHELL_BROWSER_UI_STATUS_ICON_GTK_H_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "ui/base/glib/glib_integers.h"
|
||||||
|
#include "ui/base/glib/glib_signal.h"
|
||||||
|
#include "ui/base/glib/scoped_gobject.h"
|
||||||
|
#include "ui/linux/status_icon_linux.h"
|
||||||
|
|
||||||
|
typedef struct _GtkStatusIcon GtkStatusIcon;
|
||||||
|
|
||||||
|
namespace electron {
|
||||||
|
|
||||||
|
namespace gtkui {
|
||||||
|
class MenuGtk;
|
||||||
|
}
|
||||||
|
|
||||||
|
class StatusIconGtk : public ui::StatusIconLinux {
|
||||||
|
public:
|
||||||
|
StatusIconGtk();
|
||||||
|
StatusIconGtk(const StatusIconGtk&) = delete;
|
||||||
|
StatusIconGtk& operator=(const StatusIconGtk&) = delete;
|
||||||
|
~StatusIconGtk() override;
|
||||||
|
|
||||||
|
// ui::StatusIconLinux:
|
||||||
|
void SetIcon(const gfx::ImageSkia& image) override;
|
||||||
|
void SetToolTip(const std::u16string& tool_tip) override;
|
||||||
|
void UpdatePlatformContextMenu(ui::MenuModel* model) override;
|
||||||
|
void RefreshPlatformContextMenu() override;
|
||||||
|
void OnSetDelegate() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
CHROMEG_CALLBACK_0(StatusIconGtk, void, OnClick, GtkStatusIcon*);
|
||||||
|
CHROMEG_CALLBACK_2(StatusIconGtk,
|
||||||
|
void,
|
||||||
|
OnContextMenuRequested,
|
||||||
|
GtkStatusIcon*,
|
||||||
|
guint,
|
||||||
|
guint);
|
||||||
|
|
||||||
|
std::unique_ptr<gtkui::MenuGtk> menu_;
|
||||||
|
ScopedGObject<GtkStatusIcon> icon_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace electron
|
||||||
|
|
||||||
|
#endif // ELECTRON_SHELL_BROWSER_UI_STATUS_ICON_GTK_H_
|
|
@ -1,96 +0,0 @@
|
||||||
// Copyright (c) 2014 GitHub, Inc.
|
|
||||||
// Use of this source code is governed by the MIT license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#include "shell/browser/ui/tray_icon_gtk.h"
|
|
||||||
|
|
||||||
#include "base/strings/utf_string_conversions.h"
|
|
||||||
#include "chrome/browser/ui/views/status_icons/status_icon_linux_dbus.h"
|
|
||||||
#include "ui/gfx/image/image_skia_rep.h"
|
|
||||||
|
|
||||||
namespace electron {
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
gfx::ImageSkia GetBestImageRep(const gfx::ImageSkia& image) {
|
|
||||||
image.EnsureRepsForSupportedScales();
|
|
||||||
float best_scale = 0.0f;
|
|
||||||
SkBitmap best_rep;
|
|
||||||
for (const auto& rep : image.image_reps()) {
|
|
||||||
if (rep.scale() > best_scale) {
|
|
||||||
best_scale = rep.scale();
|
|
||||||
best_rep = rep.GetBitmap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// All status icon implementations want the image in pixel coordinates, so use
|
|
||||||
// a scale factor of 1.
|
|
||||||
return gfx::ImageSkia::CreateFromBitmap(best_rep, 1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
TrayIconGtk::TrayIconGtk()
|
|
||||||
: status_icon_(new StatusIconLinuxDbus),
|
|
||||||
status_icon_type_(StatusIconType::kDbus) {
|
|
||||||
status_icon_->SetDelegate(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
TrayIconGtk::~TrayIconGtk() = default;
|
|
||||||
|
|
||||||
void TrayIconGtk::SetImage(const gfx::Image& image) {
|
|
||||||
image_ = GetBestImageRep(image.AsImageSkia());
|
|
||||||
if (status_icon_)
|
|
||||||
status_icon_->SetIcon(image_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TrayIconGtk::SetToolTip(const std::string& tool_tip) {
|
|
||||||
tool_tip_ = base::UTF8ToUTF16(tool_tip);
|
|
||||||
if (status_icon_)
|
|
||||||
status_icon_->SetToolTip(tool_tip_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TrayIconGtk::SetContextMenu(ElectronMenuModel* menu_model) {
|
|
||||||
menu_model_ = menu_model;
|
|
||||||
if (status_icon_)
|
|
||||||
status_icon_->UpdatePlatformContextMenu(menu_model_);
|
|
||||||
}
|
|
||||||
|
|
||||||
const gfx::ImageSkia& TrayIconGtk::GetImage() const {
|
|
||||||
return image_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::u16string& TrayIconGtk::GetToolTip() const {
|
|
||||||
return tool_tip_;
|
|
||||||
}
|
|
||||||
|
|
||||||
ui::MenuModel* TrayIconGtk::GetMenuModel() const {
|
|
||||||
return menu_model_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TrayIconGtk::OnImplInitializationFailed() {
|
|
||||||
switch (status_icon_type_) {
|
|
||||||
case StatusIconType::kDbus:
|
|
||||||
status_icon_ = nullptr;
|
|
||||||
status_icon_type_ = StatusIconType::kNone;
|
|
||||||
return;
|
|
||||||
case StatusIconType::kNone:
|
|
||||||
NOTREACHED();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TrayIconGtk::OnClick() {
|
|
||||||
NotifyClicked();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TrayIconGtk::HasClickAction() {
|
|
||||||
// Returning true will make the tooltip show as an additional context menu
|
|
||||||
// item, which makes sense in Chrome but not in most Electron apps.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
TrayIcon* TrayIcon::Create(absl::optional<UUID> guid) {
|
|
||||||
return new TrayIconGtk;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace electron
|
|
115
shell/browser/ui/tray_icon_linux.cc
Normal file
115
shell/browser/ui/tray_icon_linux.cc
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
// Copyright (c) 2014 GitHub, Inc.
|
||||||
|
// Use of this source code is governed by the MIT license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#include "shell/browser/ui/tray_icon_linux.h"
|
||||||
|
|
||||||
|
#include "base/strings/utf_string_conversions.h"
|
||||||
|
#include "chrome/browser/ui/views/status_icons/status_icon_linux_dbus.h"
|
||||||
|
#include "shell/browser/ui/status_icon_gtk.h"
|
||||||
|
#include "ui/gfx/image/image_skia_rep.h"
|
||||||
|
|
||||||
|
namespace electron {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
gfx::ImageSkia GetBestImageRep(const gfx::ImageSkia& image) {
|
||||||
|
image.EnsureRepsForSupportedScales();
|
||||||
|
float best_scale = 0.0f;
|
||||||
|
SkBitmap best_rep;
|
||||||
|
for (const auto& rep : image.image_reps()) {
|
||||||
|
if (rep.scale() > best_scale) {
|
||||||
|
best_scale = rep.scale();
|
||||||
|
best_rep = rep.GetBitmap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// All status icon implementations want the image in pixel coordinates, so use
|
||||||
|
// a scale factor of 1.
|
||||||
|
return gfx::ImageSkia::CreateFromBitmap(best_rep, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
TrayIconLinux::TrayIconLinux()
|
||||||
|
: status_icon_dbus_(new StatusIconLinuxDbus),
|
||||||
|
status_icon_type_(StatusIconType::kDbus) {
|
||||||
|
status_icon_dbus_->SetDelegate(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
TrayIconLinux::~TrayIconLinux() = default;
|
||||||
|
|
||||||
|
void TrayIconLinux::SetImage(const gfx::Image& image) {
|
||||||
|
image_ = GetBestImageRep(image.AsImageSkia());
|
||||||
|
if (auto* status_icon = GetStatusIcon())
|
||||||
|
status_icon->SetIcon(image_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrayIconLinux::SetToolTip(const std::string& tool_tip) {
|
||||||
|
tool_tip_ = base::UTF8ToUTF16(tool_tip);
|
||||||
|
if (auto* status_icon = GetStatusIcon())
|
||||||
|
status_icon->SetToolTip(tool_tip_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrayIconLinux::SetContextMenu(ElectronMenuModel* menu_model) {
|
||||||
|
menu_model_ = menu_model;
|
||||||
|
if (auto* status_icon = GetStatusIcon())
|
||||||
|
status_icon->UpdatePlatformContextMenu(menu_model_);
|
||||||
|
}
|
||||||
|
|
||||||
|
const gfx::ImageSkia& TrayIconLinux::GetImage() const {
|
||||||
|
return image_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::u16string& TrayIconLinux::GetToolTip() const {
|
||||||
|
return tool_tip_;
|
||||||
|
}
|
||||||
|
|
||||||
|
ui::MenuModel* TrayIconLinux::GetMenuModel() const {
|
||||||
|
return menu_model_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrayIconLinux::OnImplInitializationFailed() {
|
||||||
|
switch (status_icon_type_) {
|
||||||
|
case StatusIconType::kDbus:
|
||||||
|
status_icon_dbus_.reset();
|
||||||
|
status_icon_gtk_ = std::make_unique<StatusIconGtk>();
|
||||||
|
status_icon_type_ = StatusIconType::kGtk;
|
||||||
|
status_icon_gtk_->SetDelegate(this);
|
||||||
|
return;
|
||||||
|
case StatusIconType::kGtk:
|
||||||
|
status_icon_gtk_.reset();
|
||||||
|
status_icon_type_ = StatusIconType::kNone;
|
||||||
|
menu_model_ = nullptr;
|
||||||
|
return;
|
||||||
|
case StatusIconType::kNone:
|
||||||
|
NOTREACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrayIconLinux::OnClick() {
|
||||||
|
NotifyClicked();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TrayIconLinux::HasClickAction() {
|
||||||
|
// Returning true will make the tooltip show as an additional context menu
|
||||||
|
// item, which makes sense in Chrome but not in most Electron apps.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ui::StatusIconLinux* TrayIconLinux::GetStatusIcon() {
|
||||||
|
switch (status_icon_type_) {
|
||||||
|
case StatusIconType::kDbus:
|
||||||
|
return status_icon_dbus_.get();
|
||||||
|
case StatusIconType::kGtk:
|
||||||
|
return status_icon_gtk_.get();
|
||||||
|
case StatusIconType::kNone:
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
TrayIcon* TrayIcon::Create(absl::optional<UUID> guid) {
|
||||||
|
return new TrayIconLinux;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace electron
|
|
@ -2,8 +2,8 @@
|
||||||
// Use of this source code is governed by the MIT license that can be
|
// Use of this source code is governed by the MIT license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
#ifndef ELECTRON_SHELL_BROWSER_UI_TRAY_ICON_GTK_H_
|
#ifndef ELECTRON_SHELL_BROWSER_UI_TRAY_ICON_LINUX_H_
|
||||||
#define ELECTRON_SHELL_BROWSER_UI_TRAY_ICON_GTK_H_
|
#define ELECTRON_SHELL_BROWSER_UI_TRAY_ICON_LINUX_H_
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -15,10 +15,12 @@ class StatusIconLinuxDbus;
|
||||||
|
|
||||||
namespace electron {
|
namespace electron {
|
||||||
|
|
||||||
class TrayIconGtk : public TrayIcon, public ui::StatusIconLinux::Delegate {
|
class StatusIconGtk;
|
||||||
|
|
||||||
|
class TrayIconLinux : public TrayIcon, public ui::StatusIconLinux::Delegate {
|
||||||
public:
|
public:
|
||||||
TrayIconGtk();
|
TrayIconLinux();
|
||||||
~TrayIconGtk() override;
|
~TrayIconLinux() override;
|
||||||
|
|
||||||
// TrayIcon:
|
// TrayIcon:
|
||||||
void SetImage(const gfx::Image& image) override;
|
void SetImage(const gfx::Image& image) override;
|
||||||
|
@ -28,8 +30,6 @@ class TrayIconGtk : public TrayIcon, public ui::StatusIconLinux::Delegate {
|
||||||
// ui::StatusIconLinux::Delegate
|
// ui::StatusIconLinux::Delegate
|
||||||
void OnClick() override;
|
void OnClick() override;
|
||||||
bool HasClickAction() override;
|
bool HasClickAction() override;
|
||||||
// The following four methods are only used by StatusIconLinuxDbus, which we
|
|
||||||
// aren't yet using, so they are given stub implementations.
|
|
||||||
const gfx::ImageSkia& GetImage() const override;
|
const gfx::ImageSkia& GetImage() const override;
|
||||||
const std::u16string& GetToolTip() const override;
|
const std::u16string& GetToolTip() const override;
|
||||||
ui::MenuModel* GetMenuModel() const override;
|
ui::MenuModel* GetMenuModel() const override;
|
||||||
|
@ -38,10 +38,14 @@ class TrayIconGtk : public TrayIcon, public ui::StatusIconLinux::Delegate {
|
||||||
private:
|
private:
|
||||||
enum class StatusIconType {
|
enum class StatusIconType {
|
||||||
kDbus,
|
kDbus,
|
||||||
|
kGtk,
|
||||||
kNone,
|
kNone,
|
||||||
};
|
};
|
||||||
|
|
||||||
scoped_refptr<StatusIconLinuxDbus> status_icon_;
|
ui::StatusIconLinux* GetStatusIcon();
|
||||||
|
|
||||||
|
scoped_refptr<StatusIconLinuxDbus> status_icon_dbus_;
|
||||||
|
std::unique_ptr<StatusIconGtk> status_icon_gtk_;
|
||||||
StatusIconType status_icon_type_;
|
StatusIconType status_icon_type_;
|
||||||
|
|
||||||
gfx::ImageSkia image_;
|
gfx::ImageSkia image_;
|
||||||
|
@ -51,4 +55,4 @@ class TrayIconGtk : public TrayIcon, public ui::StatusIconLinux::Delegate {
|
||||||
|
|
||||||
} // namespace electron
|
} // namespace electron
|
||||||
|
|
||||||
#endif // ELECTRON_SHELL_BROWSER_UI_TRAY_ICON_GTK_H_
|
#endif // ELECTRON_SHELL_BROWSER_UI_TRAY_ICON_LINUX_H_
|
Loading…
Reference in a new issue