From 9afa94f4b8a9f9ebe6ac3851f638bcfbd71ddc2e Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 29 Jul 2015 12:36:01 +0800 Subject: [PATCH 1/8] win: Implement double-clicked event --- atom/browser/ui/win/notify_icon.cc | 15 +++++++++------ atom/browser/ui/win/notify_icon.h | 4 +++- atom/browser/ui/win/notify_icon_host.cc | 7 ++++++- atom/common/api/atom_api_native_image.cc | 1 + 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/atom/browser/ui/win/notify_icon.cc b/atom/browser/ui/win/notify_icon.cc index 450fd081404..ed422b882a8 100644 --- a/atom/browser/ui/win/notify_icon.cc +++ b/atom/browser/ui/win/notify_icon.cc @@ -63,7 +63,8 @@ NotifyIcon::~NotifyIcon() { } void NotifyIcon::HandleClickEvent(const gfx::Point& cursor_pos, - bool left_mouse_click) { + bool left_mouse_click, + bool double_button_click) { NOTIFYICONIDENTIFIER icon_id; memset(&icon_id, 0, sizeof(NOTIFYICONIDENTIFIER)); icon_id.uID = icon_id_; @@ -72,14 +73,16 @@ void NotifyIcon::HandleClickEvent(const gfx::Point& cursor_pos, RECT rect = { 0 }; Shell_NotifyIconGetRect(&icon_id, &rect); - // Pass to the observer if appropriate. if (left_mouse_click) { - NotifyClicked(gfx::Rect(rect)); + if (double_button_click) // double left click + NotifyDoubleClicked(gfx::Rect(rect)); + else // single left click + NotifyClicked(gfx::Rect(rect)); return; + } else if (!double_button_click) { // single right click + NotifyRightClicked(gfx::Rect(rect)); + PopContextMenu(cursor_pos); } - - NotifyRightClicked(gfx::Rect(rect)); - PopContextMenu(cursor_pos); } void NotifyIcon::ResetIcon() { diff --git a/atom/browser/ui/win/notify_icon.h b/atom/browser/ui/win/notify_icon.h index 25ba8c8dc43..c004d5f3940 100644 --- a/atom/browser/ui/win/notify_icon.h +++ b/atom/browser/ui/win/notify_icon.h @@ -33,7 +33,9 @@ class NotifyIcon : public TrayIcon { // Handles a click event from the user - if |left_button_click| is true and // there is a registered observer, passes the click event to the observer, // otherwise displays the context menu if there is one. - void HandleClickEvent(const gfx::Point& cursor_pos, bool left_button_click); + void HandleClickEvent(const gfx::Point& cursor_pos, + bool left_button_click, + bool double_button_click); // Re-creates the status tray icon now after the taskbar has been created. void ResetIcon(); diff --git a/atom/browser/ui/win/notify_icon_host.cc b/atom/browser/ui/win/notify_icon_host.cc index 4aac629f248..33ac722a537 100644 --- a/atom/browser/ui/win/notify_icon_host.cc +++ b/atom/browser/ui/win/notify_icon_host.cc @@ -146,12 +146,17 @@ LRESULT CALLBACK NotifyIconHost::WndProc(HWND hwnd, case WM_LBUTTONDOWN: case WM_RBUTTONDOWN: + case WM_LBUTTONDBLCLK: + case WM_RBUTTONDBLCLK: case WM_CONTEXTMENU: // Walk our icons, find which one was clicked on, and invoke its // HandleClickEvent() method. gfx::Point cursor_pos( gfx::Screen::GetNativeScreen()->GetCursorScreenPoint()); - win_icon->HandleClickEvent(cursor_pos, lparam == WM_LBUTTONDOWN); + win_icon->HandleClickEvent( + cursor_pos, + (lparam == WM_LBUTTONDOWN || lparam == WM_LBUTTONDBLCLK), + (lparam == WM_LBUTTONDBLCLK || lparam == WM_RBUTTONDBLCLK)); return TRUE; } } diff --git a/atom/common/api/atom_api_native_image.cc b/atom/common/api/atom_api_native_image.cc index ee9bb71a4d2..7819e314178 100644 --- a/atom/common/api/atom_api_native_image.cc +++ b/atom/common/api/atom_api_native_image.cc @@ -183,6 +183,7 @@ void NativeImage::SetTemplateImage(bool setAsTemplate) { } bool NativeImage::IsTemplateImage() { + return false; } #endif From 15273c1f7ac10af886ade2e103fb83d12f4f4d9f Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 29 Jul 2015 12:41:40 +0800 Subject: [PATCH 2/8] docs: Don't say things that are expected --- docs/api/tray.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/api/tray.md b/docs/api/tray.md index 47b5d7e3fed..935430b7fea 100644 --- a/docs/api/tray.md +++ b/docs/api/tray.md @@ -71,8 +71,7 @@ __Note:__ The `bounds` payload is only implemented on OS X and Windows 7 or newe Emitted when the tray icon is right clicked. -__Note:__ This is only implemented on OS X and Windows. On Windows, this event -will be emitted if the tray icon has context menu. +__Note:__ This is only implemented on OS X and Windows. ### Event: 'double-clicked' @@ -86,7 +85,7 @@ will be emitted if the tray icon has context menu. Emitted when the tray icon is double clicked. -__Note:__ This is only implemented on OS X. +__Note:__ This is only implemented on OS X and Windows. ### Event: 'balloon-show' @@ -171,9 +170,10 @@ __Note:__ This is only implemented on Windows. * `x` Integer * `y` Integer -__Note:__ This is only implemented on OS X and Windows. The `position` is only available on Windows, and it is (0, 0) by default. +__Note:__ This is only implemented on OS X and Windows. + ### Tray.setContextMenu(menu) * `menu` Menu From 74248253f591ca20b42a154bf39225f747a0fd3a Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 29 Jul 2015 12:55:44 +0800 Subject: [PATCH 3/8] win: Set GUID when getting icon's bounds --- atom/browser/ui/win/notify_icon.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/atom/browser/ui/win/notify_icon.cc b/atom/browser/ui/win/notify_icon.cc index ed422b882a8..b58b5931276 100644 --- a/atom/browser/ui/win/notify_icon.cc +++ b/atom/browser/ui/win/notify_icon.cc @@ -70,6 +70,11 @@ void NotifyIcon::HandleClickEvent(const gfx::Point& cursor_pos, icon_id.uID = icon_id_; icon_id.hWnd = window_; icon_id.cbSize = sizeof(NOTIFYICONIDENTIFIER); + if (has_tray_app_id_hash_) + memcpy(reinterpret_cast(&icon_id.guidItem), + &tray_app_id_hash_, + sizeof(GUID)); + RECT rect = { 0 }; Shell_NotifyIconGetRect(&icon_id, &rect); From d42fd6fc7ee307d6a463c4f52e7acf9e78f54a3d Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 29 Jul 2015 13:10:51 +0800 Subject: [PATCH 4/8] win: Pass modifers in 'clicked' events --- atom/browser/ui/win/notify_icon.cc | 7 ++++--- atom/browser/ui/win/notify_icon.h | 1 + atom/browser/ui/win/notify_icon_host.cc | 14 ++++++++++++++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/atom/browser/ui/win/notify_icon.cc b/atom/browser/ui/win/notify_icon.cc index b58b5931276..fd9a90ae1d5 100644 --- a/atom/browser/ui/win/notify_icon.cc +++ b/atom/browser/ui/win/notify_icon.cc @@ -63,6 +63,7 @@ NotifyIcon::~NotifyIcon() { } void NotifyIcon::HandleClickEvent(const gfx::Point& cursor_pos, + int modifiers, bool left_mouse_click, bool double_button_click) { NOTIFYICONIDENTIFIER icon_id; @@ -80,12 +81,12 @@ void NotifyIcon::HandleClickEvent(const gfx::Point& cursor_pos, if (left_mouse_click) { if (double_button_click) // double left click - NotifyDoubleClicked(gfx::Rect(rect)); + NotifyDoubleClicked(gfx::Rect(rect), modifiers); else // single left click - NotifyClicked(gfx::Rect(rect)); + NotifyClicked(gfx::Rect(rect), modifiers); return; } else if (!double_button_click) { // single right click - NotifyRightClicked(gfx::Rect(rect)); + NotifyRightClicked(gfx::Rect(rect), modifiers); PopContextMenu(cursor_pos); } } diff --git a/atom/browser/ui/win/notify_icon.h b/atom/browser/ui/win/notify_icon.h index c004d5f3940..a28a00ff0d6 100644 --- a/atom/browser/ui/win/notify_icon.h +++ b/atom/browser/ui/win/notify_icon.h @@ -34,6 +34,7 @@ class NotifyIcon : public TrayIcon { // there is a registered observer, passes the click event to the observer, // otherwise displays the context menu if there is one. void HandleClickEvent(const gfx::Point& cursor_pos, + int modifiers, bool left_button_click, bool double_button_click); diff --git a/atom/browser/ui/win/notify_icon_host.cc b/atom/browser/ui/win/notify_icon_host.cc index 33ac722a537..c34e14375e7 100644 --- a/atom/browser/ui/win/notify_icon_host.cc +++ b/atom/browser/ui/win/notify_icon_host.cc @@ -11,7 +11,9 @@ #include "base/stl_util.h" #include "base/threading/non_thread_safe.h" #include "base/threading/thread.h" +#include "base/win/win_util.h" #include "base/win/wrapped_window_proc.h" +#include "ui/events/event_constants.h" #include "ui/gfx/screen.h" #include "ui/gfx/win/hwnd_util.h" @@ -26,6 +28,17 @@ const UINT kBaseIconId = 2; const wchar_t kNotifyIconHostWindowClass[] = L"Electron_NotifyIconHostWindow"; +int GetKeyboardModifers() { + int modifiers = ui::EF_NONE; + if (base::win::IsShiftPressed()) + modifiers |= ui::EF_SHIFT_DOWN; + if (base::win::IsCtrlPressed()) + modifiers |= ui::EF_CONTROL_DOWN; + if (base::win::IsAltPressed()) + modifiers |= ui::EF_ALT_DOWN; + return modifiers; +} + } // namespace NotifyIconHost::NotifyIconHost() @@ -155,6 +168,7 @@ LRESULT CALLBACK NotifyIconHost::WndProc(HWND hwnd, gfx::Screen::GetNativeScreen()->GetCursorScreenPoint()); win_icon->HandleClickEvent( cursor_pos, + GetKeyboardModifers(), (lparam == WM_LBUTTONDOWN || lparam == WM_LBUTTONDBLCLK), (lparam == WM_LBUTTONDBLCLK || lparam == WM_RBUTTONDBLCLK)); return TRUE; From 625143426a23507e7fb70714d29314b2f8a17bca Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 29 Jul 2015 14:24:45 +0800 Subject: [PATCH 5/8] Enable using custom events when emitting --- atom/browser/api/event_emitter.cc | 13 ++++++++++--- atom/browser/api/event_emitter.h | 28 +++++++++++++++++++++++----- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/atom/browser/api/event_emitter.cc b/atom/browser/api/event_emitter.cc index 7337830780f..aa0b6c8781a 100644 --- a/atom/browser/api/event_emitter.cc +++ b/atom/browser/api/event_emitter.cc @@ -37,9 +37,8 @@ v8::Local CreateEventObject(v8::Isolate* isolate) { EventEmitter::EventEmitter() { } -v8::Local EventEmitter::CreateJSEvent(v8::Isolate* isolate, - content::WebContents* sender, - IPC::Message* message) { +v8::Local EventEmitter::CreateJSEvent( + v8::Isolate* isolate, content::WebContents* sender, IPC::Message* message) { v8::Local event; bool use_native_event = sender && message; @@ -54,4 +53,12 @@ v8::Local EventEmitter::CreateJSEvent(v8::Isolate* isolate, return event; } +v8::Local EventEmitter::CreateCustomEvent( + v8::Isolate* isolate, v8::Local custom_event) { + v8::Local event = CreateEventObject(isolate); + event->SetPrototype(custom_event->CreationContext(), custom_event); + mate::Dictionary(isolate, event).Set("sender", GetWrapper(isolate)); + return event; +} + } // namespace mate diff --git a/atom/browser/api/event_emitter.h b/atom/browser/api/event_emitter.h index 6910df3a28d..178c61d853c 100644 --- a/atom/browser/api/event_emitter.h +++ b/atom/browser/api/event_emitter.h @@ -25,6 +25,14 @@ class EventEmitter : public Wrappable { public: typedef std::vector> ValueArray; + // this.emit(name, event, args...); + template + bool EmitCustomEvent(const base::StringPiece& name, + v8::Local event, + const Args&... args) { + return EmitWithEvent(name, CreateCustomEvent(isolate(), event), args...); + } + // this.emit(name, new Event(), args...); template bool Emit(const base::StringPiece& name, const Args&... args) { @@ -37,21 +45,31 @@ class EventEmitter : public Wrappable { content::WebContents* sender, IPC::Message* message, const Args&... args) { - v8::Locker locker(isolate()); - v8::HandleScope handle_scope(isolate()); v8::Local event = CreateJSEvent(isolate(), sender, message); - EmitEvent(isolate(), GetWrapper(isolate()), name, event, args...); - return event->Get( - StringToV8(isolate(), "defaultPrevented"))->BooleanValue(); + return EmitWithEvent(name, event, args...); } protected: EventEmitter(); private: + // this.emit(name, event, args...); + template + bool EmitWithEvent(const base::StringPiece& name, + v8::Local event, + const Args&... args) { + v8::Locker locker(isolate()); + v8::HandleScope handle_scope(isolate()); + EmitEvent(isolate(), GetWrapper(isolate()), name, event, args...); + return event->Get( + StringToV8(isolate(), "defaultPrevented"))->BooleanValue(); + } + v8::Local CreateJSEvent(v8::Isolate* isolate, content::WebContents* sender, IPC::Message* message); + v8::Local CreateCustomEvent( + v8::Isolate* isolate, v8::Local event); DISALLOW_COPY_AND_ASSIGN(EventEmitter); }; From 8d22eeb3be7ce0b4d6c1393cf686f63fa3aa21c1 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 29 Jul 2015 14:25:12 +0800 Subject: [PATCH 6/8] Use DOM's way of telling modifiers --- atom/browser/api/atom_api_tray.cc | 31 +++++++++++++++++++++++++------ atom/browser/api/atom_api_tray.h | 4 +++- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/atom/browser/api/atom_api_tray.cc b/atom/browser/api/atom_api_tray.cc index a849c03f59a..82f78519aeb 100644 --- a/atom/browser/api/atom_api_tray.cc +++ b/atom/browser/api/atom_api_tray.cc @@ -14,6 +14,7 @@ #include "atom/common/native_mate_converters/string16_converter.h" #include "native_mate/constructor.h" #include "native_mate/dictionary.h" +#include "ui/events/event_constants.h" #include "ui/gfx/image/image.h" #include "atom/common/node_includes.h" @@ -41,11 +42,24 @@ mate::Wrappable* Tray::New(v8::Isolate* isolate, const gfx::Image& image) { } void Tray::OnClicked(const gfx::Rect& bounds, int modifiers) { - Emit("clicked", bounds, modifiers); + v8::Locker locker(isolate()); + v8::HandleScope handle_scope(isolate()); + EmitCustomEvent("clicked", + ModifiersToObject(isolate(), modifiers), bounds); } void Tray::OnDoubleClicked(const gfx::Rect& bounds, int modifiers) { - Emit("double-clicked", bounds, modifiers); + v8::Locker locker(isolate()); + v8::HandleScope handle_scope(isolate()); + EmitCustomEvent("double-clicked", + ModifiersToObject(isolate(), modifiers), bounds); +} + +void Tray::OnRightClicked(const gfx::Rect& bounds, int modifiers) { + v8::Locker locker(isolate()); + v8::HandleScope handle_scope(isolate()); + EmitCustomEvent("right-clicked", + ModifiersToObject(isolate(), modifiers), bounds); } void Tray::OnBalloonShow() { @@ -60,10 +74,6 @@ void Tray::OnBalloonClosed() { Emit("balloon-closed"); } -void Tray::OnRightClicked(const gfx::Rect& bounds, int modifiers) { - Emit("right-clicked", bounds, modifiers); -} - void Tray::OnDropFiles(const std::vector& files) { Emit("drop-files", files); } @@ -120,6 +130,15 @@ void Tray::SetContextMenu(mate::Arguments* args, Menu* menu) { tray_icon_->SetContextMenu(menu->model()); } +v8::Local Tray::ModifiersToObject(v8::Isolate* isolate, + int modifiers) { + mate::Dictionary obj(isolate, v8::Object::New(isolate)); + obj.Set("shiftKey", static_cast(modifiers & ui::EF_SHIFT_DOWN)); + obj.Set("ctrlKey", static_cast(modifiers & ui::EF_CONTROL_DOWN)); + obj.Set("altKey", static_cast(modifiers & ui::EF_ALT_DOWN)); + return obj.GetHandle(); +} + // static void Tray::BuildPrototype(v8::Isolate* isolate, v8::Local prototype) { diff --git a/atom/browser/api/atom_api_tray.h b/atom/browser/api/atom_api_tray.h index 10340677813..02f7418fe41 100644 --- a/atom/browser/api/atom_api_tray.h +++ b/atom/browser/api/atom_api_tray.h @@ -44,10 +44,10 @@ class Tray : public mate::EventEmitter, // TrayIconObserver: void OnClicked(const gfx::Rect& bounds, int modifiers) override; void OnDoubleClicked(const gfx::Rect& bounds, int modifiers) override; + void OnRightClicked(const gfx::Rect& bounds, int modifiers) override; void OnBalloonShow() override; void OnBalloonClicked() override; void OnBalloonClosed() override; - void OnRightClicked(const gfx::Rect& bounds, int modifiers) override; void OnDropFiles(const std::vector& files) override; // mate::Wrappable: @@ -64,6 +64,8 @@ class Tray : public mate::EventEmitter, void SetContextMenu(mate::Arguments* args, Menu* menu); private: + v8::Local ModifiersToObject(v8::Isolate* isolate, int modifiers); + scoped_ptr tray_icon_; DISALLOW_COPY_AND_ASSIGN(Tray); From 3e1a5b229ce2750182ec1ac1070142d73dd03d02 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 29 Jul 2015 14:27:32 +0800 Subject: [PATCH 7/8] docs: modifiers removed --- docs/api/tray.md | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/docs/api/tray.md b/docs/api/tray.md index 935430b7fea..5c8c88018f7 100644 --- a/docs/api/tray.md +++ b/docs/api/tray.md @@ -47,13 +47,15 @@ Creates a new tray icon associated with the `image`. ### Event: 'clicked' -* `event` +* `event` Event + * `altKey` Boolean + * `shiftKey` Boolean + * `ctrlKey` Boolean * `bounds` Object - the bounds of tray icon * `x` Integer * `y` Integer * `width` Integer * `height` Integer -* [`modifiers`][modifiers] Integer - bitsum of keyboard modifiers and mouse keys Emitted when the tray icon is clicked. @@ -61,13 +63,15 @@ __Note:__ The `bounds` payload is only implemented on OS X and Windows 7 or newe ### Event: 'right-clicked' -* `event` +* `event` Event + * `altKey` Boolean + * `shiftKey` Boolean + * `ctrlKey` Boolean * `bounds` Object - the bounds of tray icon * `x` Integer * `y` Integer * `width` Integer * `height` Integer -* [`modifiers`][modifiers] Integer - bitsum of keyboard modifiers and mouse keys Emitted when the tray icon is right clicked. @@ -75,13 +79,15 @@ __Note:__ This is only implemented on OS X and Windows. ### Event: 'double-clicked' -* `event` +* `event` Event + * `altKey` Boolean + * `shiftKey` Boolean + * `ctrlKey` Boolean * `bounds` Object - the bounds of tray icon * `x` Integer * `y` Integer * `width` Integer * `height` Integer -* [`modifiers`][modifiers] Integer - bitsum of keyboard modifiers and mouse keys Emitted when the tray icon is double clicked. @@ -181,4 +187,3 @@ __Note:__ This is only implemented on OS X and Windows. Sets the context menu for this icon. [event-emitter]: http://nodejs.org/api/events.html#events_class_events_eventemitter -[modifiers]: https://code.google.com/p/chromium/codesearch#chromium/src/ui/events/event_constants.h&l=77 From b2f03fc2d878061d3c001dbc2cb21676db6e35fd Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 29 Jul 2015 14:44:08 +0800 Subject: [PATCH 8/8] Add metaKey --- atom/browser/api/atom_api_tray.cc | 1 + atom/browser/ui/win/notify_icon_host.cc | 8 ++++++++ docs/api/tray.md | 3 +++ 3 files changed, 12 insertions(+) diff --git a/atom/browser/api/atom_api_tray.cc b/atom/browser/api/atom_api_tray.cc index 82f78519aeb..0f07737da2b 100644 --- a/atom/browser/api/atom_api_tray.cc +++ b/atom/browser/api/atom_api_tray.cc @@ -136,6 +136,7 @@ v8::Local Tray::ModifiersToObject(v8::Isolate* isolate, obj.Set("shiftKey", static_cast(modifiers & ui::EF_SHIFT_DOWN)); obj.Set("ctrlKey", static_cast(modifiers & ui::EF_CONTROL_DOWN)); obj.Set("altKey", static_cast(modifiers & ui::EF_ALT_DOWN)); + obj.Set("metaKey", static_cast(modifiers & ui::EF_COMMAND_DOWN)); return obj.GetHandle(); } diff --git a/atom/browser/ui/win/notify_icon_host.cc b/atom/browser/ui/win/notify_icon_host.cc index c34e14375e7..2c84837e714 100644 --- a/atom/browser/ui/win/notify_icon_host.cc +++ b/atom/browser/ui/win/notify_icon_host.cc @@ -5,6 +5,7 @@ #include "atom/browser/ui/win/notify_icon_host.h" #include +#include #include "atom/browser/ui/win/notify_icon.h" #include "base/bind.h" @@ -28,6 +29,11 @@ const UINT kBaseIconId = 2; const wchar_t kNotifyIconHostWindowClass[] = L"Electron_NotifyIconHostWindow"; +bool IsWinPressed() { + return ((::GetKeyState(VK_LWIN) & 0x8000) == 0x8000) || + ((::GetKeyState(VK_RWIN) & 0x8000) == 0x8000); +} + int GetKeyboardModifers() { int modifiers = ui::EF_NONE; if (base::win::IsShiftPressed()) @@ -36,6 +42,8 @@ int GetKeyboardModifers() { modifiers |= ui::EF_CONTROL_DOWN; if (base::win::IsAltPressed()) modifiers |= ui::EF_ALT_DOWN; + if (IsWinPressed()) + modifiers |= ui::EF_COMMAND_DOWN; return modifiers; } diff --git a/docs/api/tray.md b/docs/api/tray.md index 5c8c88018f7..3d3ebc280f5 100644 --- a/docs/api/tray.md +++ b/docs/api/tray.md @@ -51,6 +51,7 @@ Creates a new tray icon associated with the `image`. * `altKey` Boolean * `shiftKey` Boolean * `ctrlKey` Boolean + * `metaKey` Boolean * `bounds` Object - the bounds of tray icon * `x` Integer * `y` Integer @@ -67,6 +68,7 @@ __Note:__ The `bounds` payload is only implemented on OS X and Windows 7 or newe * `altKey` Boolean * `shiftKey` Boolean * `ctrlKey` Boolean + * `metaKey` Boolean * `bounds` Object - the bounds of tray icon * `x` Integer * `y` Integer @@ -83,6 +85,7 @@ __Note:__ This is only implemented on OS X and Windows. * `altKey` Boolean * `shiftKey` Boolean * `ctrlKey` Boolean + * `metaKey` Boolean * `bounds` Object - the bounds of tray icon * `x` Integer * `y` Integer