Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/tray/SDL_tray_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ void SDL_CleanupTrays(void)
SDL_DestroyTray((SDL_Tray *)trays[i]);
}
SDL_free(trays);

SDL_PropertiesID g = SDL_GetGlobalProperties();
if (g) {
SDL_ClearProperty(g, SDL_PROP_TRAY_CLEANUP);
}
}

bool SDL_HasActiveTrays(void)
Expand Down
2 changes: 2 additions & 0 deletions src/tray/SDL_tray_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
*/
#include "SDL_internal.h"

#define SDL_PROP_TRAY_CLEANUP "SDL.PROP.Tray.Cleanup"

extern void SDL_RegisterTray(SDL_Tray *tray);
extern void SDL_UnregisterTray(SDL_Tray *tray);
extern void SDL_CleanupTrays(void);
Expand Down
64 changes: 61 additions & 3 deletions src/tray/windows/SDL_tray.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,20 @@ LRESULT CALLBACK TrayWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lPar
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

static UINT s_taskbarRestart = 0;
if (s_taskbarRestart == 0) {
s_taskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));
}
if(uMsg == s_taskbarRestart) {
Shell_NotifyIconW(NIM_ADD, &tray->nid);
Shell_NotifyIconW(NIM_SETVERSION, &tray->nid);
}

switch (uMsg) {
case WM_TRAYICON:
if (LOWORD(lParam) == WM_CONTEXTMENU || LOWORD(lParam) == WM_LBUTTONUP) {
SetForegroundWindow(hwnd);

if (tray->menu) {
TrackPopupMenu(tray->menu->hMenu, TPM_BOTTOMALIGN | TPM_RIGHTALIGN, GET_X_LPARAM(wParam), GET_Y_LPARAM(wParam), 0, hwnd, NULL);
}
Expand Down Expand Up @@ -216,6 +225,51 @@ void SDL_UpdateTrays(void)
{
}

static void SDL_PropTrayCleanupCb(void* userdata, void* cls) {
WNDCLASSEX wcex;

wcex.hIcon = NULL;
wcex.hIconSm = NULL;
HINSTANCE h = GetModuleHandle(NULL);
if (GetClassInfoEx(h, cls, &wcex)) {
UnregisterClass(cls, h);
}
}

static bool SDL_RegisterTrayClass(LPCWSTR className)
{
SDL_PropertiesID g = SDL_GetGlobalProperties();
if (!g) {
return false;
}
void* p = SDL_GetPointerProperty(g, SDL_PROP_TRAY_CLEANUP, NULL);
if (p) {
return true;
}

WNDCLASSEX wcex;

wcex.cbSize = sizeof(WNDCLASSEX);
wcex.hCursor = NULL;
wcex.hIcon = NULL;
wcex.hIconSm = NULL;
wcex.lpszMenuName = NULL;
wcex.lpszClassName = className;
wcex.style = 0;
wcex.hbrBackground = NULL;
wcex.lpfnWndProc = TrayWindowProc;
wcex.hInstance = NULL;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;

if (!RegisterClassEx(&wcex)) {
return SDL_SetError("Couldn't register tray class");
}

SDL_SetPointerPropertyWithCleanup(g, SDL_PROP_TRAY_CLEANUP, (void*)wcex.lpszClassName, SDL_PropTrayCleanupCb, NULL);
return true;
}

SDL_Tray *SDL_CreateTray(SDL_Surface *icon, const char *tooltip)
{
if (!SDL_IsMainThread()) {
Expand All @@ -230,8 +284,12 @@ SDL_Tray *SDL_CreateTray(SDL_Surface *icon, const char *tooltip)
}

tray->menu = NULL;
tray->hwnd = CreateWindowEx(0, TEXT("Message"), NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL);
SetWindowLongPtr(tray->hwnd, GWLP_WNDPROC, (LONG_PTR) TrayWindowProc);
if (!SDL_RegisterTrayClass(TEXT("SDL_TRAY"))) {
SDL_SetError("Failed to register SDL_TRAY window class");
return NULL;
}
tray->hwnd = CreateWindowEx(0, TEXT("SDL_TRAY"), NULL, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, NULL, NULL);

WIN_UpdateDarkModeForHWND(tray->hwnd);

Expand Down
Loading