Skip to content

Commit bdbfb7c

Browse files
committed
tray(Win32): re-add the tray icon upon taskbar restart
1 parent 9ed83e7 commit bdbfb7c

File tree

3 files changed

+68
-3
lines changed

3 files changed

+68
-3
lines changed

src/tray/SDL_tray_utils.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@ void SDL_CleanupTrays(void)
8383
SDL_DestroyTray((SDL_Tray *)trays[i]);
8484
}
8585
SDL_free(trays);
86+
87+
SDL_PropertiesID g = SDL_GetGlobalProperties();
88+
if (g) {
89+
SDL_ClearProperty(g, SDL_PROP_TRAY_CLEANUP);
90+
}
8691
}
8792

8893
bool SDL_HasActiveTrays(void)

src/tray/SDL_tray_utils.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
*/
2121
#include "SDL_internal.h"
2222

23+
#define SDL_PROP_TRAY_CLEANUP "SDL.PROP.Tray.Cleanup"
24+
2325
extern void SDL_RegisterTray(SDL_Tray *tray);
2426
extern void SDL_UnregisterTray(SDL_Tray *tray);
2527
extern void SDL_CleanupTrays(void);

src/tray/windows/SDL_tray.c

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,20 @@ LRESULT CALLBACK TrayWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lPar
111111
return DefWindowProc(hwnd, uMsg, wParam, lParam);
112112
}
113113

114+
static UINT s_taskbarRestart = 0;
115+
if (s_taskbarRestart == 0) {
116+
s_taskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));
117+
}
118+
if(uMsg == s_taskbarRestart) {
119+
Shell_NotifyIconW(NIM_ADD, &tray->nid);
120+
Shell_NotifyIconW(NIM_SETVERSION, &tray->nid);
121+
}
122+
114123
switch (uMsg) {
115124
case WM_TRAYICON:
116125
if (LOWORD(lParam) == WM_CONTEXTMENU || LOWORD(lParam) == WM_LBUTTONUP) {
117126
SetForegroundWindow(hwnd);
118-
127+
119128
if (tray->menu) {
120129
TrackPopupMenu(tray->menu->hMenu, TPM_BOTTOMALIGN | TPM_RIGHTALIGN, GET_X_LPARAM(wParam), GET_Y_LPARAM(wParam), 0, hwnd, NULL);
121130
}
@@ -216,6 +225,51 @@ void SDL_UpdateTrays(void)
216225
{
217226
}
218227

228+
static void SDL_PropTrayCleanupCb(void* userdata, void* cls) {
229+
WNDCLASSEX wcex;
230+
231+
wcex.hIcon = NULL;
232+
wcex.hIconSm = NULL;
233+
HINSTANCE h = GetModuleHandle(NULL);
234+
if (GetClassInfoEx(h, cls, &wcex)) {
235+
UnregisterClass(cls, h);
236+
}
237+
}
238+
239+
static bool SDL_RegisterTrayClass(LPCWSTR className)
240+
{
241+
SDL_PropertiesID g = SDL_GetGlobalProperties();
242+
if (!g) {
243+
return false;
244+
}
245+
void* p = SDL_GetPointerProperty(g, SDL_PROP_TRAY_CLEANUP, NULL);
246+
if (p) {
247+
return true;
248+
}
249+
250+
WNDCLASSEX wcex;
251+
252+
wcex.cbSize = sizeof(WNDCLASSEX);
253+
wcex.hCursor = NULL;
254+
wcex.hIcon = NULL;
255+
wcex.hIconSm = NULL;
256+
wcex.lpszMenuName = NULL;
257+
wcex.lpszClassName = className;
258+
wcex.style = 0;
259+
wcex.hbrBackground = NULL;
260+
wcex.lpfnWndProc = TrayWindowProc;
261+
wcex.hInstance = NULL;
262+
wcex.cbClsExtra = 0;
263+
wcex.cbWndExtra = 0;
264+
265+
if (!RegisterClassEx(&wcex)) {
266+
return SDL_SetError("Couldn't register tray class");
267+
}
268+
269+
SDL_SetPointerPropertyWithCleanup(g, SDL_PROP_TRAY_CLEANUP, (void*)wcex.lpszClassName, SDL_PropTrayCleanupCb, NULL);
270+
return true;
271+
}
272+
219273
SDL_Tray *SDL_CreateTray(SDL_Surface *icon, const char *tooltip)
220274
{
221275
if (!SDL_IsMainThread()) {
@@ -230,8 +284,12 @@ SDL_Tray *SDL_CreateTray(SDL_Surface *icon, const char *tooltip)
230284
}
231285

232286
tray->menu = NULL;
233-
tray->hwnd = CreateWindowEx(0, TEXT("Message"), NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL);
234-
SetWindowLongPtr(tray->hwnd, GWLP_WNDPROC, (LONG_PTR) TrayWindowProc);
287+
if (!SDL_RegisterTrayClass(TEXT("SDL_TRAY"))) {
288+
SDL_SetError("Failed to register SDL_TRAY window class");
289+
return NULL;
290+
}
291+
tray->hwnd = CreateWindowEx(0, TEXT("SDL_TRAY"), NULL, WS_OVERLAPPEDWINDOW,
292+
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, NULL, NULL);
235293

236294
WIN_UpdateDarkModeForHWND(tray->hwnd);
237295

0 commit comments

Comments
 (0)