diff --git a/src/runner/tray_icon.cpp b/src/runner/tray_icon.cpp index a693e20d7a8..c2be73692da 100644 --- a/src/runner/tray_icon.cpp +++ b/src/runner/tray_icon.cpp @@ -6,20 +6,24 @@ extern "C" IMAGE_DOS_HEADER __ImageBase; -HWND tray_icon_hwnd = NULL; +namespace { + HWND tray_icon_hwnd = NULL; -// Message code that Windows will use for tray icon notifications. -UINT wm_icon_notify = 0; + // Message code that Windows will use for tray icon notifications. + UINT wm_icon_notify = 0; -// Contains the Windows Message for taskbar creation. -UINT wm_taskbar_restart = 0; -UINT wm_run_on_main_ui_thread = 0; + // Contains the Windows Message for taskbar creation. + UINT wm_taskbar_restart = 0; + UINT wm_run_on_main_ui_thread = 0; -NOTIFYICONDATAW tray_icon_data; -static bool about_box_shown = false; + NOTIFYICONDATAW tray_icon_data; + bool tray_icon_created = false; -HMENU h_menu = nullptr; -HMENU h_sub_menu = nullptr; + bool about_box_shown = false; + + HMENU h_menu = nullptr; + HMENU h_sub_menu = nullptr; +} // Struct to fill with callback and the data. The window_proc is responsible for cleaning it. struct run_on_main_ui_thread_msg { @@ -77,6 +81,16 @@ LRESULT __stdcall tray_icon_window_proc(HWND window, UINT message, WPARAM wparam break; } break; + // Shell_NotifyIcon can fail when we invoke it during the time explorer.exe isn't present/ready to handle it. + // We'll also never receive wm_taskbar_restart message if the first call to Shell_NotifyIcon failed, so we use + // WM_WINDOWPOSCHANGING which is always received on explorer startup sequence. + case WM_WINDOWPOSCHANGING: + { + if(!tray_icon_created) { + tray_icon_created = Shell_NotifyIcon(NIM_ADD, &tray_icon_data) == TRUE; + } + break; + } default: if (message == wm_icon_notify) { switch(lparam) { @@ -110,7 +124,7 @@ LRESULT __stdcall tray_icon_window_proc(HWND window, UINT message, WPARAM wparam } break; } else if (message == wm_taskbar_restart) { - Shell_NotifyIcon(NIM_ADD, &tray_icon_data); + tray_icon_created = Shell_NotifyIcon(NIM_ADD, &tray_icon_data) == TRUE; break; } } @@ -154,6 +168,6 @@ void start_tray_icon() { wcscpy_s(tray_icon_data.szTip, sizeof(tray_icon_data.szTip) / sizeof(WCHAR), L"PowerToys"); tray_icon_data.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE; - Shell_NotifyIcon(NIM_ADD, &tray_icon_data); + tray_icon_created = Shell_NotifyIcon(NIM_ADD, &tray_icon_data) == TRUE; } }