| 
									
										
										
										
											2014-10-31 11:17:05 -07:00
										 |  |  | // Copyright (c) 2014 GitHub, Inc.
 | 
					
						
							| 
									
										
										
										
											2014-06-03 11:25:09 +08:00
										 |  |  | // Use of this source code is governed by the MIT license that can be
 | 
					
						
							|  |  |  | // found in the LICENSE file.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-19 13:46:59 -07:00
										 |  |  | #include "shell/browser/ui/win/notify_icon_host.h"
 | 
					
						
							| 
									
										
										
										
											2014-06-03 11:25:09 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <commctrl.h>
 | 
					
						
							| 
									
										
										
										
											2015-07-29 14:44:08 +08:00
										 |  |  | #include <winuser.h>
 | 
					
						
							| 
									
										
										
										
											2014-06-03 11:25:09 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-03 12:43:42 +01:00
										 |  |  | #include "base/functional/bind.h"
 | 
					
						
							| 
									
										
										
										
											2020-07-13 18:13:34 -07:00
										 |  |  | #include "base/logging.h"
 | 
					
						
							| 
									
										
										
										
											2020-11-29 23:49:30 -08:00
										 |  |  | #include "base/memory/weak_ptr.h"
 | 
					
						
							| 
									
										
										
										
											2023-10-10 01:56:38 +02:00
										 |  |  | #include "base/timer/timer.h"
 | 
					
						
							| 
									
										
										
										
											2015-07-29 13:10:51 +08:00
										 |  |  | #include "base/win/win_util.h"
 | 
					
						
							| 
									
										
										
										
											2020-07-13 18:13:34 -07:00
										 |  |  | #include "base/win/windows_types.h"
 | 
					
						
							| 
									
										
										
										
											2014-06-03 11:25:09 +08:00
										 |  |  | #include "base/win/wrapped_window_proc.h"
 | 
					
						
							| 
									
										
										
										
											2023-04-12 07:37:48 -04:00
										 |  |  | #include "content/public/browser/browser_thread.h"
 | 
					
						
							| 
									
										
										
										
											2019-06-19 13:46:59 -07:00
										 |  |  | #include "shell/browser/ui/win/notify_icon.h"
 | 
					
						
							| 
									
										
										
										
											2023-10-10 01:56:38 +02:00
										 |  |  | #include "ui/display/screen.h"
 | 
					
						
							| 
									
										
										
										
											2015-07-29 13:10:51 +08:00
										 |  |  | #include "ui/events/event_constants.h"
 | 
					
						
							| 
									
										
										
										
											2016-03-09 11:22:54 -08:00
										 |  |  | #include "ui/events/win/system_event_state_lookup.h"
 | 
					
						
							| 
									
										
										
										
											2014-06-03 11:25:09 +08:00
										 |  |  | #include "ui/gfx/win/hwnd_util.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace electron { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const UINT kNotifyIconMessage = WM_APP + 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // |kBaseIconId| is 2 to avoid conflicts with plugins that hard-code id 1.
 | 
					
						
							|  |  |  | const UINT kBaseIconId = 2; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-14 16:18:57 +08:00
										 |  |  | const wchar_t kNotifyIconHostWindowClass[] = L"Electron_NotifyIconHostWindow"; | 
					
						
							| 
									
										
										
										
											2014-06-03 11:25:09 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-10 01:56:38 +02:00
										 |  |  | constexpr unsigned int kMouseLeaveCheckFrequency = 250; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-29 14:44:08 +08:00
										 |  |  | bool IsWinPressed() { | 
					
						
							|  |  |  |   return ((::GetKeyState(VK_LWIN) & 0x8000) == 0x8000) || | 
					
						
							|  |  |  |          ((::GetKeyState(VK_RWIN) & 0x8000) == 0x8000); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-29 23:49:30 -08:00
										 |  |  | int GetKeyboardModifiers() { | 
					
						
							| 
									
										
										
										
											2015-07-29 13:10:51 +08:00
										 |  |  |   int modifiers = ui::EF_NONE; | 
					
						
							| 
									
										
										
										
											2016-03-09 11:22:54 -08:00
										 |  |  |   if (ui::win::IsShiftPressed()) | 
					
						
							| 
									
										
										
										
											2015-07-29 13:10:51 +08:00
										 |  |  |     modifiers |= ui::EF_SHIFT_DOWN; | 
					
						
							| 
									
										
										
										
											2016-03-09 11:22:54 -08:00
										 |  |  |   if (ui::win::IsCtrlPressed()) | 
					
						
							| 
									
										
										
										
											2015-07-29 13:10:51 +08:00
										 |  |  |     modifiers |= ui::EF_CONTROL_DOWN; | 
					
						
							| 
									
										
										
										
											2016-03-09 11:22:54 -08:00
										 |  |  |   if (ui::win::IsAltPressed()) | 
					
						
							| 
									
										
										
										
											2015-07-29 13:10:51 +08:00
										 |  |  |     modifiers |= ui::EF_ALT_DOWN; | 
					
						
							| 
									
										
										
										
											2015-07-29 14:44:08 +08:00
										 |  |  |   if (IsWinPressed()) | 
					
						
							|  |  |  |     modifiers |= ui::EF_COMMAND_DOWN; | 
					
						
							| 
									
										
										
										
											2015-07-29 13:10:51 +08:00
										 |  |  |   return modifiers; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-03 11:25:09 +08:00
										 |  |  | }  // namespace
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-10 01:56:38 +02:00
										 |  |  | // Helper class used to detect mouse entered and mouse exited events based on
 | 
					
						
							|  |  |  | // mouse move event.
 | 
					
						
							|  |  |  | class NotifyIconHost::MouseEnteredExitedDetector { | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   MouseEnteredExitedDetector() = default; | 
					
						
							|  |  |  |   ~MouseEnteredExitedDetector() = default; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // disallow copy
 | 
					
						
							|  |  |  |   MouseEnteredExitedDetector(const MouseEnteredExitedDetector&) = delete; | 
					
						
							|  |  |  |   MouseEnteredExitedDetector& operator=(const MouseEnteredExitedDetector&) = | 
					
						
							|  |  |  |       delete; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // disallow move
 | 
					
						
							|  |  |  |   MouseEnteredExitedDetector(MouseEnteredExitedDetector&&) = delete; | 
					
						
							|  |  |  |   MouseEnteredExitedDetector& operator=(MouseEnteredExitedDetector&&) = delete; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void MouseMoveEvent(raw_ptr<NotifyIcon> icon) { | 
					
						
							|  |  |  |     if (!icon) | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // If cursor is out of icon then skip this move event.
 | 
					
						
							|  |  |  |     if (!IsCursorOverIcon(icon)) | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // If user moved cursor to other icon then send mouse exited event for
 | 
					
						
							|  |  |  |     // old icon.
 | 
					
						
							|  |  |  |     if (current_mouse_entered_ && | 
					
						
							|  |  |  |         current_mouse_entered_->icon_id() != icon->icon_id()) { | 
					
						
							|  |  |  |       SendExitedEvent(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-12 19:51:56 -08:00
										 |  |  |     // If timer is running then cursor is already over icon and
 | 
					
						
							|  |  |  |     // CheckCursorPositionOverIcon will be repeatedly checking when to send
 | 
					
						
							| 
									
										
										
										
											2023-10-10 01:56:38 +02:00
										 |  |  |     // mouse exited event.
 | 
					
						
							|  |  |  |     if (mouse_exit_timer_.IsRunning()) | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     SendEnteredEvent(icon); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-12 19:51:56 -08:00
										 |  |  |     // Start repeatedly checking when to send mouse exited event.
 | 
					
						
							| 
									
										
										
										
											2023-10-10 01:56:38 +02:00
										 |  |  |     StartObservingIcon(icon); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void IconRemoved(raw_ptr<NotifyIcon> icon) { | 
					
						
							|  |  |  |     if (current_mouse_entered_ && | 
					
						
							|  |  |  |         current_mouse_entered_->icon_id() == icon->icon_id()) { | 
					
						
							|  |  |  |       SendExitedEvent(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  private: | 
					
						
							|  |  |  |   void SendEnteredEvent(raw_ptr<NotifyIcon> icon) { | 
					
						
							|  |  |  |     content::GetUIThreadTaskRunner({})->PostTask( | 
					
						
							|  |  |  |         FROM_HERE, base::BindOnce(&NotifyIcon::HandleMouseEntered, | 
					
						
							|  |  |  |                                   icon->GetWeakPtr(), GetKeyboardModifiers())); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void SendExitedEvent() { | 
					
						
							|  |  |  |     mouse_exit_timer_.Stop(); | 
					
						
							|  |  |  |     content::GetUIThreadTaskRunner({})->PostTask( | 
					
						
							|  |  |  |         FROM_HERE, base::BindOnce(&NotifyIcon::HandleMouseExited, | 
					
						
							|  |  |  |                                   std::move(current_mouse_entered_), | 
					
						
							|  |  |  |                                   GetKeyboardModifiers())); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bool IsCursorOverIcon(raw_ptr<NotifyIcon> icon) { | 
					
						
							|  |  |  |     gfx::Point cursor_pos = | 
					
						
							|  |  |  |         display::Screen::GetScreen()->GetCursorScreenPoint(); | 
					
						
							|  |  |  |     return icon->GetBounds().Contains(cursor_pos); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void CheckCursorPositionOverIcon() { | 
					
						
							|  |  |  |     if (!current_mouse_entered_ || | 
					
						
							|  |  |  |         IsCursorOverIcon(current_mouse_entered_.get())) | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     SendExitedEvent(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void StartObservingIcon(raw_ptr<NotifyIcon> icon) { | 
					
						
							|  |  |  |     current_mouse_entered_ = icon->GetWeakPtr(); | 
					
						
							|  |  |  |     mouse_exit_timer_.Start( | 
					
						
							|  |  |  |         FROM_HERE, base::Milliseconds(kMouseLeaveCheckFrequency), | 
					
						
							|  |  |  |         base::BindRepeating( | 
					
						
							|  |  |  |             &MouseEnteredExitedDetector::CheckCursorPositionOverIcon, | 
					
						
							|  |  |  |             weak_factory_.GetWeakPtr())); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Timer used to check if cursor is still over the icon.
 | 
					
						
							|  |  |  |   base::MetronomeTimer mouse_exit_timer_; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Weak pointer to icon over which cursor is hovering.
 | 
					
						
							|  |  |  |   base::WeakPtr<NotifyIcon> current_mouse_entered_; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   base::WeakPtrFactory<MouseEnteredExitedDetector> weak_factory_{this}; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-22 00:18:38 +02:00
										 |  |  | NotifyIconHost::NotifyIconHost() { | 
					
						
							| 
									
										
										
										
											2014-06-03 11:25:09 +08:00
										 |  |  |   // Register our window class
 | 
					
						
							|  |  |  |   WNDCLASSEX window_class; | 
					
						
							|  |  |  |   base::win::InitializeWindowClass( | 
					
						
							|  |  |  |       kNotifyIconHostWindowClass, | 
					
						
							| 
									
										
										
										
											2018-04-17 21:55:30 -04:00
										 |  |  |       &base::win::WrappedWindowProc<NotifyIconHost::WndProcStatic>, 0, 0, 0, | 
					
						
							| 
									
										
										
										
											2023-10-03 21:26:35 +02:00
										 |  |  |       nullptr, nullptr, nullptr, nullptr, nullptr, &window_class); | 
					
						
							| 
									
										
										
										
											2014-06-03 11:25:09 +08:00
										 |  |  |   instance_ = window_class.hInstance; | 
					
						
							|  |  |  |   atom_ = RegisterClassEx(&window_class); | 
					
						
							|  |  |  |   CHECK(atom_); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // If the taskbar is re-created after we start up, we have to rebuild all of
 | 
					
						
							|  |  |  |   // our icons.
 | 
					
						
							|  |  |  |   taskbar_created_message_ = RegisterWindowMessage(TEXT("TaskbarCreated")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Create an offscreen window for handling messages for the status icons. We
 | 
					
						
							|  |  |  |   // create a hidden WS_POPUP window instead of an HWND_MESSAGE window, because
 | 
					
						
							|  |  |  |   // only top-level windows such as popups can receive broadcast messages like
 | 
					
						
							|  |  |  |   // "TaskbarCreated".
 | 
					
						
							| 
									
										
										
										
											2018-04-17 21:55:30 -04:00
										 |  |  |   window_ = CreateWindow(MAKEINTATOM(atom_), 0, WS_POPUP, 0, 0, 0, 0, 0, 0, | 
					
						
							|  |  |  |                          instance_, 0); | 
					
						
							| 
									
										
										
										
											2020-07-13 18:13:34 -07:00
										 |  |  |   gfx::CheckWindowCreated(window_, ::GetLastError()); | 
					
						
							| 
									
										
										
										
											2014-06-03 11:25:09 +08:00
										 |  |  |   gfx::SetWindowUserData(window_, this); | 
					
						
							| 
									
										
										
										
											2023-10-10 01:56:38 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   mouse_entered_exited_detector_ = | 
					
						
							|  |  |  |       std::make_unique<MouseEnteredExitedDetector>(); | 
					
						
							| 
									
										
										
										
											2014-06-03 11:25:09 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | NotifyIconHost::~NotifyIconHost() { | 
					
						
							|  |  |  |   if (window_) | 
					
						
							|  |  |  |     DestroyWindow(window_); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (atom_) | 
					
						
							|  |  |  |     UnregisterClass(MAKEINTATOM(atom_), instance_); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-26 16:10:28 +09:00
										 |  |  |   for (NotifyIcon* ptr : notify_icons_) | 
					
						
							|  |  |  |     delete ptr; | 
					
						
							| 
									
										
										
										
											2014-06-03 11:25:09 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-10 23:23:35 +01:00
										 |  |  | NotifyIcon* NotifyIconHost::CreateNotifyIcon(std::optional<UUID> guid) { | 
					
						
							| 
									
										
										
										
											2020-01-30 21:37:03 -08:00
										 |  |  |   if (guid.has_value()) { | 
					
						
							|  |  |  |     for (NotifyIcons::const_iterator i(notify_icons_.begin()); | 
					
						
							|  |  |  |          i != notify_icons_.end(); ++i) { | 
					
						
							| 
									
										
										
										
											2020-10-26 11:56:31 -07:00
										 |  |  |       auto* current_win_icon = static_cast<NotifyIcon*>(*i); | 
					
						
							| 
									
										
										
										
											2020-01-30 21:37:03 -08:00
										 |  |  |       if (current_win_icon->guid() == guid.value()) { | 
					
						
							|  |  |  |         LOG(WARNING) | 
					
						
							|  |  |  |             << "Guid already in use. Existing tray entry will be replaced."; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-26 11:56:31 -07:00
										 |  |  |   auto* notify_icon = | 
					
						
							| 
									
										
										
										
											2020-01-30 21:37:03 -08:00
										 |  |  |       new NotifyIcon(this, NextIconId(), window_, kNotifyIconMessage, | 
					
						
							|  |  |  |                      guid.has_value() ? guid.value() : GUID_DEFAULT); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-03 11:25:09 +08:00
										 |  |  |   notify_icons_.push_back(notify_icon); | 
					
						
							|  |  |  |   return notify_icon; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NotifyIconHost::Remove(NotifyIcon* icon) { | 
					
						
							| 
									
										
										
										
											2024-08-26 09:58:32 -05:00
										 |  |  |   const auto i = std::ranges::find(notify_icons_, icon); | 
					
						
							| 
									
										
										
										
											2014-06-03 11:25:09 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (i == notify_icons_.end()) { | 
					
						
							|  |  |  |     NOTREACHED(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-10 01:56:38 +02:00
										 |  |  |   mouse_entered_exited_detector_->IconRemoved(*i); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-03 11:25:09 +08:00
										 |  |  |   notify_icons_.erase(i); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | LRESULT CALLBACK NotifyIconHost::WndProcStatic(HWND hwnd, | 
					
						
							| 
									
										
										
										
											2018-04-17 21:55:30 -04:00
										 |  |  |                                                UINT message, | 
					
						
							|  |  |  |                                                WPARAM wparam, | 
					
						
							|  |  |  |                                                LPARAM lparam) { | 
					
						
							| 
									
										
										
										
											2020-10-26 11:56:31 -07:00
										 |  |  |   auto* msg_wnd = | 
					
						
							| 
									
										
										
										
											2018-04-17 21:55:30 -04:00
										 |  |  |       reinterpret_cast<NotifyIconHost*>(GetWindowLongPtr(hwnd, GWLP_USERDATA)); | 
					
						
							| 
									
										
										
										
											2014-06-03 11:25:09 +08:00
										 |  |  |   if (msg_wnd) | 
					
						
							|  |  |  |     return msg_wnd->WndProc(hwnd, message, wparam, lparam); | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     return ::DefWindowProc(hwnd, message, wparam, lparam); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | LRESULT CALLBACK NotifyIconHost::WndProc(HWND hwnd, | 
					
						
							| 
									
										
										
										
											2018-04-17 21:55:30 -04:00
										 |  |  |                                          UINT message, | 
					
						
							|  |  |  |                                          WPARAM wparam, | 
					
						
							|  |  |  |                                          LPARAM lparam) { | 
					
						
							| 
									
										
										
										
											2014-06-03 11:25:09 +08:00
										 |  |  |   if (message == taskbar_created_message_) { | 
					
						
							|  |  |  |     // We need to reset all of our icons because the taskbar went away.
 | 
					
						
							| 
									
										
										
										
											2024-08-26 09:58:32 -05:00
										 |  |  |     std::ranges::for_each(notify_icons_, [](auto* icon) { icon->ResetIcon(); }); | 
					
						
							| 
									
										
										
										
											2014-06-03 11:25:09 +08:00
										 |  |  |     return TRUE; | 
					
						
							|  |  |  |   } else if (message == kNotifyIconMessage) { | 
					
						
							| 
									
										
										
										
											2023-10-03 21:26:35 +02:00
										 |  |  |     NotifyIcon* win_icon = nullptr; | 
					
						
							| 
									
										
										
										
											2014-06-03 11:25:09 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // Find the selected status icon.
 | 
					
						
							|  |  |  |     for (NotifyIcons::const_iterator i(notify_icons_.begin()); | 
					
						
							|  |  |  |          i != notify_icons_.end(); ++i) { | 
					
						
							| 
									
										
										
										
											2020-10-26 11:56:31 -07:00
										 |  |  |       auto* current_win_icon = static_cast<NotifyIcon*>(*i); | 
					
						
							| 
									
										
										
										
											2014-06-03 11:25:09 +08:00
										 |  |  |       if (current_win_icon->icon_id() == wparam) { | 
					
						
							|  |  |  |         win_icon = current_win_icon; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // It is possible for this procedure to be called with an obsolete icon
 | 
					
						
							|  |  |  |     // id.  In that case we should just return early before handling any
 | 
					
						
							|  |  |  |     // actions.
 | 
					
						
							|  |  |  |     if (!win_icon) | 
					
						
							|  |  |  |       return TRUE; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-29 23:49:30 -08:00
										 |  |  |     // We use a WeakPtr factory for NotifyIcons here so
 | 
					
						
							|  |  |  |     // that the callback is aware if the NotifyIcon gets
 | 
					
						
							|  |  |  |     // garbage-collected. This occurs when the tray gets
 | 
					
						
							|  |  |  |     // GC'd, and the BALLOON events below will not emit.
 | 
					
						
							|  |  |  |     base::WeakPtr<NotifyIcon> win_icon_weak = win_icon->GetWeakPtr(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-03 11:25:09 +08:00
										 |  |  |     switch (lparam) { | 
					
						
							| 
									
										
										
										
											2019-08-01 23:00:37 +02:00
										 |  |  |       case NIN_BALLOONSHOW: | 
					
						
							| 
									
										
										
										
											2020-11-29 23:49:30 -08:00
										 |  |  |         content::GetUIThreadTaskRunner({})->PostTask( | 
					
						
							|  |  |  |             FROM_HERE, | 
					
						
							|  |  |  |             base::BindOnce(&NotifyIcon::NotifyBalloonShow, win_icon_weak)); | 
					
						
							| 
									
										
										
										
											2014-11-28 19:42:57 +08:00
										 |  |  |         return TRUE; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-01 23:00:37 +02:00
										 |  |  |       case NIN_BALLOONUSERCLICK: | 
					
						
							| 
									
										
										
										
											2020-11-29 23:49:30 -08:00
										 |  |  |         content::GetUIThreadTaskRunner({})->PostTask( | 
					
						
							|  |  |  |             FROM_HERE, | 
					
						
							|  |  |  |             base::BindOnce(&NotifyIcon::NotifyBalloonClicked, win_icon_weak)); | 
					
						
							| 
									
										
										
										
											2014-11-28 19:42:57 +08:00
										 |  |  |         return TRUE; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-01 23:00:37 +02:00
										 |  |  |       case NIN_BALLOONTIMEOUT: | 
					
						
							| 
									
										
										
										
											2020-11-29 23:49:30 -08:00
										 |  |  |         content::GetUIThreadTaskRunner({})->PostTask( | 
					
						
							|  |  |  |             FROM_HERE, | 
					
						
							|  |  |  |             base::BindOnce(&NotifyIcon::NotifyBalloonClosed, win_icon_weak)); | 
					
						
							| 
									
										
										
										
											2014-11-28 18:50:31 +08:00
										 |  |  |         return TRUE; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-03 11:25:09 +08:00
										 |  |  |       case WM_LBUTTONDOWN: | 
					
						
							|  |  |  |       case WM_RBUTTONDOWN: | 
					
						
							| 
									
										
										
										
											2023-09-27 20:21:15 +02:00
										 |  |  |       case WM_MBUTTONDOWN: | 
					
						
							| 
									
										
										
										
											2015-07-29 12:36:01 +08:00
										 |  |  |       case WM_LBUTTONDBLCLK: | 
					
						
							|  |  |  |       case WM_RBUTTONDBLCLK: | 
					
						
							| 
									
										
										
										
											2023-09-27 20:21:15 +02:00
										 |  |  |       case WM_MBUTTONDBLCLK: | 
					
						
							| 
									
										
										
										
											2014-06-03 11:25:09 +08:00
										 |  |  |       case WM_CONTEXTMENU: | 
					
						
							|  |  |  |         // Walk our icons, find which one was clicked on, and invoke its
 | 
					
						
							|  |  |  |         // HandleClickEvent() method.
 | 
					
						
							| 
									
										
										
										
											2020-11-29 23:49:30 -08:00
										 |  |  |         content::GetUIThreadTaskRunner({})->PostTask( | 
					
						
							|  |  |  |             FROM_HERE, | 
					
						
							|  |  |  |             base::BindOnce( | 
					
						
							|  |  |  |                 &NotifyIcon::HandleClickEvent, win_icon_weak, | 
					
						
							|  |  |  |                 GetKeyboardModifiers(), | 
					
						
							|  |  |  |                 (lparam == WM_LBUTTONDOWN || lparam == WM_LBUTTONDBLCLK), | 
					
						
							| 
									
										
										
										
											2023-09-27 20:21:15 +02:00
										 |  |  |                 (lparam == WM_LBUTTONDBLCLK || lparam == WM_RBUTTONDBLCLK), | 
					
						
							|  |  |  |                 (lparam == WM_MBUTTONDOWN || lparam == WM_MBUTTONDBLCLK))); | 
					
						
							| 
									
										
										
										
											2020-11-29 23:49:30 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-03 11:25:09 +08:00
										 |  |  |         return TRUE; | 
					
						
							| 
									
										
										
										
											2019-07-18 10:52:15 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       case WM_MOUSEMOVE: | 
					
						
							| 
									
										
										
										
											2023-10-10 01:56:38 +02:00
										 |  |  |         mouse_entered_exited_detector_->MouseMoveEvent(win_icon); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-29 23:49:30 -08:00
										 |  |  |         content::GetUIThreadTaskRunner({})->PostTask( | 
					
						
							|  |  |  |             FROM_HERE, base::BindOnce(&NotifyIcon::HandleMouseMoveEvent, | 
					
						
							|  |  |  |                                       win_icon_weak, GetKeyboardModifiers())); | 
					
						
							| 
									
										
										
										
											2019-07-18 10:52:15 -07:00
										 |  |  |         return TRUE; | 
					
						
							| 
									
										
										
										
											2014-06-03 11:25:09 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return ::DefWindowProc(hwnd, message, wparam, lparam); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | UINT NotifyIconHost::NextIconId() { | 
					
						
							|  |  |  |   UINT icon_id = next_icon_id_++; | 
					
						
							|  |  |  |   return kBaseIconId + icon_id; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | }  // namespace electron
 |