Repository: electron/electron
File: shell/browser/api/electron_api_tray.cc (C++)

Code before:

gin::DeprecatedWrapperInfo Tray::kWrapperInfo = {gin::kEmbedderNativeGin};

Tray::Tray(v8::Isolate* isolate,
           v8::Local<v8::Value> image,
           std::optional<base::Uuid> guid)
    : guid_(guid), tray_icon_(TrayIcon::Create(guid)) {
  SetImage(isolate, image);
  tray_icon_->AddObserver(this);
  if (guid.has_value())
    tray_icon_->SetAutoSaveName(guid.value().AsLowercaseString());
}

Tray::~Tray() = default;

// static
gin::Handle<Tray> Tray::New(gin_helper::ErrorThrower thrower,
                            v8::Local<v8::Value> image,
                            std::optional<base::Uuid> guid,
                            gin::Arguments* args) {
  if (!Browser::Get()->is_ready()) {
    thrower.ThrowError("Cannot create Tray before app is ready");
    return {};
  }

#if BUILDFLAG(IS_WIN)
  if (!guid.has_value() && args->Length() > 1) {
    thrower.ThrowError("Invalid GUID format - GUID must be a string");
    return {};
  }
#endif

  // Error thrown by us will be dropped when entering V8.
  // Make sure to abort early and propagate the error to JS.
  // Refs https://chromium-review.googlesource.com/c/v8/v8/+/5050065
  v8::TryCatch try_catch(args->isolate());
  auto* tray = new Tray(args->isolate(), image, guid);
  if (try_catch.HasCaught()) {
    delete tray;
    try_catch.ReThrow();
    return {};
  }

  auto handle = gin::CreateHandle(args->isolate(), tray);
  handle->Pin(args->isolate());
  return handle;
}

void Tray::OnClicked(const gfx::Rect& bounds,
                     const gfx::Point& location,
                     int modifiers) {

Review comment (suggestion):
Looks like we're only checking this in Windows, but the parameter is typed as a UUID regardless. I think that means on Mac we'd get  a null value for a non-GUID string even though it sounds like Cocoa would allow a non-GUID identifier.

Code after:

gin::DeprecatedWrapperInfo Tray::kWrapperInfo = {gin::kEmbedderNativeGin};

Tray::Tray(v8::Isolate* isolate,
           v8::Local<v8::Value> image,
           std::optional<base::Uuid> guid)
    : guid_(guid), tray_icon_(TrayIcon::Create(guid)) {
  SetImage(isolate, image);
  tray_icon_->AddObserver(this);
  if (guid.has_value())
    tray_icon_->SetAutoSaveName(guid.value().AsLowercaseString());
}

Tray::~Tray() = default;

// static
gin_helper::Handle<Tray> Tray::New(gin_helper::ErrorThrower thrower,
                                   v8::Local<v8::Value> image,
                                   std::optional<base::Uuid> guid,
                                   gin::Arguments* args) {
  if (!Browser::Get()->is_ready()) {
    thrower.ThrowError("Cannot create Tray before app is ready");
    return {};
  }

  if (!guid.has_value() && args->Length() > 1) {
    thrower.ThrowError("Invalid GUID format - GUID must be a string");
    return {};
  }

  // Error thrown by us will be dropped when entering V8.
  // Make sure to abort early and propagate the error to JS.
  // Refs https://chromium-review.googlesource.com/c/v8/v8/+/5050065
  v8::TryCatch try_catch(args->isolate());
  auto* tray = new Tray(args->isolate(), image, guid);
  if (try_catch.HasCaught()) {
    delete tray;
    try_catch.ReThrow();
    return {};
  }

  auto handle = gin_helper::CreateHandle(args->isolate(), tray);
  handle->Pin(args->isolate());
  return handle;
}

void Tray::OnClicked(const gfx::Rect& bounds,
                     const gfx::Point& location,
                     int modifiers) {
  v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
  v8::HandleScope scope(isolate);