status_icon_gtk.cc 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. // Copyright (c) 2023 Microsoft, Inc.
  2. // Copyright (c) 2011 The Chromium Authors.
  3. // Use of this source code is governed by the MIT license that can be
  4. // found in the LICENSE file.
  5. #include "shell/browser/ui/status_icon_gtk.h"
  6. #include <gtk/gtk.h>
  7. #include "base/functional/bind.h"
  8. #include "base/strings/utf_string_conversions.h"
  9. #include "shell/browser/ui/gtk/menu_gtk.h"
  10. #include "shell/browser/ui/gtk_util.h"
  11. #include "ui/gfx/image/image_skia.h"
  12. namespace electron {
  13. StatusIconGtk::StatusIconGtk() : icon_(TakeGObject(gtk_status_icon_new())) {
  14. auto connect = [&](auto* sender, const char* detailed_signal, auto receiver) {
  15. // Unretained() is safe since StatusIconGtk will own the
  16. // ScopedGSignal.
  17. signals_.emplace_back(
  18. sender, detailed_signal,
  19. base::BindRepeating(receiver, base::Unretained(this)));
  20. };
  21. connect(icon_.get(), "activate", &StatusIconGtk::OnClick);
  22. connect(icon_.get(), "popup_menu", &StatusIconGtk::OnContextMenuRequested);
  23. }
  24. StatusIconGtk::~StatusIconGtk() = default;
  25. void StatusIconGtk::SetIcon(const gfx::ImageSkia& image) {
  26. if (image.isNull())
  27. return;
  28. GdkPixbuf* pixbuf = gtk_util::GdkPixbufFromSkBitmap(*image.bitmap());
  29. gtk_status_icon_set_from_pixbuf(icon_, pixbuf);
  30. g_object_unref(pixbuf);
  31. }
  32. void StatusIconGtk::SetToolTip(const std::u16string& tool_tip) {
  33. gtk_status_icon_set_tooltip_text(icon_, base::UTF16ToUTF8(tool_tip).c_str());
  34. }
  35. void StatusIconGtk::UpdatePlatformContextMenu(ui::MenuModel* model) {
  36. if (model)
  37. menu_ = std::make_unique<gtkui::MenuGtk>(model);
  38. }
  39. void StatusIconGtk::RefreshPlatformContextMenu() {
  40. if (menu_)
  41. menu_->Refresh();
  42. }
  43. void StatusIconGtk::OnSetDelegate() {
  44. SetIcon(delegate_->GetImage());
  45. SetToolTip(delegate_->GetToolTip());
  46. UpdatePlatformContextMenu(delegate_->GetMenuModel());
  47. gtk_status_icon_set_visible(icon_, TRUE);
  48. }
  49. void StatusIconGtk::OnClick(GtkStatusIcon* status_icon) {
  50. delegate_->OnClick();
  51. }
  52. void StatusIconGtk::OnContextMenuRequested(GtkStatusIcon* status_icon,
  53. guint button,
  54. guint32 activate_time) {
  55. if (menu_.get()) {
  56. gtk_menu_popup(menu_->GetGtkMenu(), nullptr, nullptr,
  57. gtk_status_icon_position_menu, icon_, button, activate_time);
  58. }
  59. }
  60. } // namespace electron