77#include < string>
88
99#include " base/threading/thread_task_runner_handle.h"
10+ #include " gin/dictionary.h"
11+ #include " gin/object_template_builder.h"
1012#include " shell/browser/api/electron_api_menu.h"
13+ #include " shell/browser/api/ui_event.h"
1114#include " shell/browser/browser.h"
1215#include " shell/common/api/electron_api_native_image.h"
1316#include " shell/common/gin_converters/gfx_converter.h"
1417#include " shell/common/gin_converters/guid_converter.h"
1518#include " shell/common/gin_converters/image_converter.h"
1619#include " shell/common/gin_helper/dictionary.h"
17- #include " shell/common/gin_helper/object_template_builder .h"
20+ #include " shell/common/gin_helper/function_template_extensions .h"
1821#include " shell/common/node_includes.h"
1922#include " ui/gfx/image/image.h"
2023
@@ -55,50 +58,50 @@ namespace electron {
5558
5659namespace api {
5760
61+ gin::WrapperInfo Tray::kWrapperInfo = {gin::kEmbedderNativeGin };
62+
5863Tray::Tray (gin::Handle<NativeImage> image,
5964 base::Optional<UUID> guid,
60- gin_helper ::Arguments* args)
65+ gin ::Arguments* args)
6166 : tray_icon_(TrayIcon::Create(guid)) {
62- SetImage (args-> isolate (), image);
67+ SetImage (image);
6368 tray_icon_->AddObserver (this );
64-
65- InitWithArgs (args);
6669}
6770
6871Tray::~Tray () = default ;
6972
7073// static
71- gin_helper::WrappableBase* Tray::New (gin_helper::ErrorThrower thrower,
72- gin::Handle<NativeImage> image,
73- base::Optional<UUID> guid,
74- gin_helper ::Arguments* args) {
74+ gin::Handle<Tray> Tray::New (gin_helper::ErrorThrower thrower,
75+ gin::Handle<NativeImage> image,
76+ base::Optional<UUID> guid,
77+ gin ::Arguments* args) {
7578 if (!Browser::Get ()->is_ready ()) {
7679 thrower.ThrowError (" Cannot create Tray before app is ready" );
77- return nullptr ;
80+ return gin::Handle<Tray>() ;
7881 }
7982
8083#if defined(OS_WIN)
8184 if (!guid.has_value () && args->Length () > 1 ) {
8285 thrower.ThrowError (" Invalid GUID format" );
83- return nullptr ;
86+ return gin::Handle<Tray>() ;
8487 }
8588#endif
8689
87- return new Tray (image, guid, args);
90+ return gin::CreateHandle (thrower. isolate (), new Tray (image, guid, args) );
8891}
8992
9093void Tray::OnClicked (const gfx::Rect& bounds,
9194 const gfx::Point& location,
9295 int modifiers) {
93- EmitWithFlags (" click" , modifiers, bounds, location);
96+ EmitCustomEvent (" click" , CreateEventFromFlags ( modifiers) , bounds, location);
9497}
9598
9699void Tray::OnDoubleClicked (const gfx::Rect& bounds, int modifiers) {
97- EmitWithFlags (" double-click" , modifiers, bounds);
100+ EmitCustomEvent (" double-click" , CreateEventFromFlags ( modifiers) , bounds);
98101}
99102
100103void Tray::OnRightClicked (const gfx::Rect& bounds, int modifiers) {
101- EmitWithFlags (" right-click" , modifiers, bounds);
104+ EmitCustomEvent (" right-click" , CreateEventFromFlags ( modifiers) , bounds);
102105}
103106
104107void Tray::OnBalloonShow () {
@@ -126,23 +129,23 @@ void Tray::OnDropText(const std::string& text) {
126129}
127130
128131void Tray::OnMouseEntered (const gfx::Point& location, int modifiers) {
129- EmitWithFlags (" mouse-enter" , modifiers, location);
132+ EmitCustomEvent (" mouse-enter" , CreateEventFromFlags ( modifiers) , location);
130133}
131134
132135void Tray::OnMouseExited (const gfx::Point& location, int modifiers) {
133- EmitWithFlags (" mouse-leave" , modifiers, location);
136+ EmitCustomEvent (" mouse-leave" , CreateEventFromFlags ( modifiers) , location);
134137}
135138
136139void Tray::OnMouseMoved (const gfx::Point& location, int modifiers) {
137- EmitWithFlags (" mouse-move" , modifiers, location);
140+ EmitCustomEvent (" mouse-move" , CreateEventFromFlags ( modifiers) , location);
138141}
139142
140143void Tray::OnMouseUp (const gfx::Point& location, int modifiers) {
141- EmitWithFlags (" mouse-up" , modifiers, location);
144+ EmitCustomEvent (" mouse-up" , CreateEventFromFlags ( modifiers) , location);
142145}
143146
144147void Tray::OnMouseDown (const gfx::Point& location, int modifiers) {
145- EmitWithFlags (" mouse-down" , modifiers, location);
148+ EmitCustomEvent (" mouse-down" , CreateEventFromFlags ( modifiers) , location);
146149}
147150
148151void Tray::OnDragEntered () {
@@ -157,16 +160,28 @@ void Tray::OnDragEnded() {
157160 Emit (" drag-end" );
158161}
159162
160- void Tray::SetImage (v8::Isolate* isolate, gin::Handle<NativeImage> image) {
163+ void Tray::Destroy () {
164+ menu_.Reset ();
165+ tray_icon_.reset ();
166+ }
167+
168+ bool Tray::IsDestroyed () {
169+ return !tray_icon_;
170+ }
171+
172+ void Tray::SetImage (gin::Handle<NativeImage> image) {
173+ if (!CheckDestroyed ())
174+ return ;
161175#if defined(OS_WIN)
162176 tray_icon_->SetImage (image->GetHICON (GetSystemMetrics (SM_CXSMICON)));
163177#else
164178 tray_icon_->SetImage (image->image ());
165179#endif
166180}
167181
168- void Tray::SetPressedImage (v8::Isolate* isolate,
169- gin::Handle<NativeImage> image) {
182+ void Tray::SetPressedImage (gin::Handle<NativeImage> image) {
183+ if (!CheckDestroyed ())
184+ return ;
170185#if defined(OS_WIN)
171186 tray_icon_->SetPressedImage (image->GetHICON (GetSystemMetrics (SM_CXSMICON)));
172187#else
@@ -175,16 +190,22 @@ void Tray::SetPressedImage(v8::Isolate* isolate,
175190}
176191
177192void Tray::SetToolTip (const std::string& tool_tip) {
193+ if (!CheckDestroyed ())
194+ return ;
178195 tray_icon_->SetToolTip (tool_tip);
179196}
180197
181198void Tray::SetTitle (const std::string& title) {
199+ if (!CheckDestroyed ())
200+ return ;
182201#if defined(OS_MACOSX)
183202 tray_icon_->SetTitle (title);
184203#endif
185204}
186205
187206std::string Tray::GetTitle () {
207+ if (!CheckDestroyed ())
208+ return std::string ();
188209#if defined(OS_MACOSX)
189210 return tray_icon_->GetTitle ();
190211#else
@@ -193,12 +214,16 @@ std::string Tray::GetTitle() {
193214}
194215
195216void Tray::SetIgnoreDoubleClickEvents (bool ignore) {
217+ if (!CheckDestroyed ())
218+ return ;
196219#if defined(OS_MACOSX)
197220 tray_icon_->SetIgnoreDoubleClickEvents (ignore);
198221#endif
199222}
200223
201224bool Tray::GetIgnoreDoubleClickEvents () {
225+ if (!CheckDestroyed ())
226+ return false ;
202227#if defined(OS_MACOSX)
203228 return tray_icon_->GetIgnoreDoubleClickEvents ();
204229#else
@@ -208,6 +233,8 @@ bool Tray::GetIgnoreDoubleClickEvents() {
208233
209234void Tray::DisplayBalloon (gin_helper::ErrorThrower thrower,
210235 const gin_helper::Dictionary& options) {
236+ if (!CheckDestroyed ())
237+ return ;
211238 TrayIcon::BalloonOptions balloon_options;
212239
213240 if (!options.Get (" title" , &balloon_options.title ) ||
@@ -236,27 +263,50 @@ void Tray::DisplayBalloon(gin_helper::ErrorThrower thrower,
236263}
237264
238265void Tray::RemoveBalloon () {
266+ if (!CheckDestroyed ())
267+ return ;
239268 tray_icon_->RemoveBalloon ();
240269}
241270
242271void Tray::Focus () {
272+ if (!CheckDestroyed ())
273+ return ;
243274 tray_icon_->Focus ();
244275}
245276
246- void Tray::PopUpContextMenu (gin_helper::Arguments* args) {
277+ void Tray::PopUpContextMenu (gin::Arguments* args) {
278+ if (!CheckDestroyed ())
279+ return ;
247280 gin::Handle<Menu> menu;
248- args->GetNext (&menu);
249281 gfx::Point pos;
250- args->GetNext (&pos);
282+
283+ v8::Local<v8::Value> first_arg;
284+ if (args->GetNext (&first_arg)) {
285+ if (!gin::ConvertFromV8 (args->isolate (), first_arg, &menu)) {
286+ if (!gin::ConvertFromV8 (args->isolate (), first_arg, &pos)) {
287+ args->ThrowError ();
288+ return ;
289+ }
290+ } else if (args->Length () >= 2 ) {
291+ if (!args->GetNext (&pos)) {
292+ args->ThrowError ();
293+ return ;
294+ }
295+ }
296+ }
251297 tray_icon_->PopUpContextMenu (pos, menu.IsEmpty () ? nullptr : menu->model ());
252298}
253299
254300void Tray::CloseContextMenu () {
301+ if (!CheckDestroyed ())
302+ return ;
255303 tray_icon_->CloseContextMenu ();
256304}
257305
258306void Tray::SetContextMenu (gin_helper::ErrorThrower thrower,
259307 v8::Local<v8::Value> arg) {
308+ if (!CheckDestroyed ())
309+ return ;
260310 gin::Handle<Menu> menu;
261311 if (arg->IsNull ()) {
262312 menu_.Reset ();
@@ -270,15 +320,29 @@ void Tray::SetContextMenu(gin_helper::ErrorThrower thrower,
270320}
271321
272322gfx::Rect Tray::GetBounds () {
323+ if (!CheckDestroyed ())
324+ return gfx::Rect ();
273325 return tray_icon_->GetBounds ();
274326}
275327
328+ bool Tray::CheckDestroyed () {
329+ if (!tray_icon_) {
330+ v8::Isolate* isolate = v8::Isolate::GetCurrent ();
331+ v8::Locker locker (isolate);
332+ v8::HandleScope scope (isolate);
333+ gin_helper::ErrorThrower (isolate).ThrowError (" Tray is destroyed" );
334+ return false ;
335+ }
336+ return true ;
337+ }
338+
276339// static
277- void Tray::BuildPrototype (v8::Isolate* isolate,
278- v8::Local<v8::FunctionTemplate> prototype) {
279- prototype->SetClassName (gin::StringToV8 (isolate, " Tray" ));
280- gin_helper::Destroyable::MakeDestroyable (isolate, prototype);
281- gin_helper::ObjectTemplateBuilder (isolate, prototype->PrototypeTemplate ())
340+ v8::Local<v8::ObjectTemplate> Tray::FillObjectTemplate (
341+ v8::Isolate* isolate,
342+ v8::Local<v8::ObjectTemplate> templ) {
343+ return gin::ObjectTemplateBuilder (isolate, " Tray" , templ)
344+ .SetMethod (" destroy" , &Tray::Destroy)
345+ .SetMethod (" isDestroyed" , &Tray::IsDestroyed)
282346 .SetMethod (" setImage" , &Tray::SetImage)
283347 .SetMethod (" setPressedImage" , &Tray::SetPressedImage)
284348 .SetMethod (" setToolTip" , &Tray::SetToolTip)
@@ -294,7 +358,8 @@ void Tray::BuildPrototype(v8::Isolate* isolate,
294358 .SetMethod (" popUpContextMenu" , &Tray::PopUpContextMenu)
295359 .SetMethod (" closeContextMenu" , &Tray::CloseContextMenu)
296360 .SetMethod (" setContextMenu" , &Tray::SetContextMenu)
297- .SetMethod (" getBounds" , &Tray::GetBounds);
361+ .SetMethod (" getBounds" , &Tray::GetBounds)
362+ .Build ();
298363}
299364
300365} // namespace api
@@ -310,12 +375,9 @@ void Initialize(v8::Local<v8::Object> exports,
310375 v8::Local<v8::Context> context,
311376 void * priv) {
312377 v8::Isolate* isolate = context->GetIsolate ();
313- Tray::SetConstructor (isolate, base::BindRepeating (&Tray::New));
314378
315- gin_helper::Dictionary dict (isolate, exports);
316- dict.Set (
317- " Tray" ,
318- Tray::GetConstructor (isolate)->GetFunction (context).ToLocalChecked ());
379+ gin::Dictionary dict (isolate, exports);
380+ dict.Set (" Tray" , Tray::GetConstructor (context));
319381}
320382
321383} // namespace
0 commit comments