From d381cbaa9b8e206bb5eacaf196e8fdce190070d5 Mon Sep 17 00:00:00 2001 From: dijunkun Date: Mon, 7 Sep 2026 17:42:25 +0800 Subject: [PATCH] [fix] show system tray icon on application startup --- .../platform/linux/gui/tray/linux_tray.cpp | 9 +++++-- .../platform/windows/gui/tray/win_tray.cpp | 24 +++++++++++++++++-- .../src/platform/windows/gui/tray/win_tray.h | 2 ++ 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/apps/desktop/src/platform/linux/gui/tray/linux_tray.cpp b/apps/desktop/src/platform/linux/gui/tray/linux_tray.cpp index 1c9dc875..4c3aa8b1 100644 --- a/apps/desktop/src/platform/linux/gui/tray/linux_tray.cpp +++ b/apps/desktop/src/platform/linux/gui/tray/linux_tray.cpp @@ -392,7 +392,10 @@ struct LinuxTrayImpl { exit_menu_label(GetExitMenuLabel(language_index_value)), exit_menu_ascii_label(IsAsciiPrintable(exit_menu_label) ? exit_menu_label - : "Exit") {} + : "Exit") { + + EnsureTrayIcon(); + } explicit LinuxTrayImpl(std::function show_window_callback, std::function hide_window_callback, @@ -416,7 +419,9 @@ struct LinuxTrayImpl { exit_menu_label(GetExitMenuLabel(language_index_value)), exit_menu_ascii_label(IsAsciiPrintable(exit_menu_label) ? exit_menu_label - : "Exit") {} + : "Exit") { + EnsureTrayIcon(); + } ~LinuxTrayImpl() { RemoveTrayIcon(); } diff --git a/apps/desktop/src/platform/windows/gui/tray/win_tray.cpp b/apps/desktop/src/platform/windows/gui/tray/win_tray.cpp index 5592e8c8..46abaec3 100644 --- a/apps/desktop/src/platform/windows/gui/tray/win_tray.cpp +++ b/apps/desktop/src/platform/windows/gui/tray/win_tray.cpp @@ -60,6 +60,8 @@ WinTray::WinTray(HWND app_hwnd, HICON icon, const std::wstring& tooltip, nid_.uCallbackMessage = WM_TRAY_CALLBACK; nid_.hIcon = icon_; wcsncpy_s(nid_.szTip, tip_.c_str(), _TRUNCATE); + + EnsureTrayIcon(); } WinTray::WinTray(std::function show_window, @@ -80,7 +82,7 @@ WinTray::~WinTray() { } void WinTray::MinimizeToTray() { - Shell_NotifyIcon(NIM_ADD, &nid_); + EnsureTrayIcon(); if (hide_window_) { hide_window_(); } else if (app_hwnd_) { @@ -88,7 +90,25 @@ void WinTray::MinimizeToTray() { } } -void WinTray::RemoveTrayIcon() { Shell_NotifyIcon(NIM_DELETE, &nid_); } +bool WinTray::EnsureTrayIcon() { + if (tray_icon_added_) { + // NIM_MODIFY also detects an icon lost when Explorer was restarted. + if (Shell_NotifyIcon(NIM_MODIFY, &nid_)) { + return true; + } + tray_icon_added_ = false; + } + + tray_icon_added_ = Shell_NotifyIcon(NIM_ADD, &nid_) != FALSE; + return tray_icon_added_; +} + +void WinTray::RemoveTrayIcon() { + if (tray_icon_added_) { + Shell_NotifyIcon(NIM_DELETE, &nid_); + tray_icon_added_ = false; + } +} void WinTray::ShowApplicationWindow() { if (show_window_) { diff --git a/apps/desktop/src/platform/windows/gui/tray/win_tray.h b/apps/desktop/src/platform/windows/gui/tray/win_tray.h index 014e7480..bc3df3c1 100644 --- a/apps/desktop/src/platform/windows/gui/tray/win_tray.h +++ b/apps/desktop/src/platform/windows/gui/tray/win_tray.h @@ -33,6 +33,7 @@ class WinTray { bool HandleTrayMessage(MSG* msg); private: + bool EnsureTrayIcon(); void ShowApplicationWindow(); void OpenSettings(); @@ -42,6 +43,7 @@ class WinTray { std::wstring tip_; int language_index_; NOTIFYICONDATA nid_; + bool tray_icon_added_ = false; std::function show_window_; std::function hide_window_; std::function open_settings_;