I have created a SDL2 application, and would like it to minimize to the system tray, rather than appearing in the task bar.
SDL_MinimizeWindow
doesn't do what I want, it leaves the task bar icon. Is there a way to achieve this with SDL?
There is no purely SDL2 way to do this, as Cody said, Shell_NotifyIcon
is the function needed to create a notification area (system tray) icon.
The code I used to get the icon is
SDL_Window *window = SDL_CreateWindow("Test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 200, 200, SDL_WINDOW_HIDDEN);
SDL_SysWMinfo info;
SDL_VERSION(&info.version);
NOTIFYICONDATA icon;
if (SDL_GetWindowWMInfo(window, &info))
{
icon.uCallbackMessage = WM_USER + 1;
icon.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE;
icon.hIcon = LoadIcon(NULL, IDI_INFORMATION);
icon.cbSize = sizeof(icon);
icon.hWnd = info.info.win.window;
strcpy_s(icon.szTip, "Test tip");
bool success = Shell_NotifyIcon(NIM_ADD, &icon);
}
This creates a hidden window, and an icon (using the default information icon).
To interact with this from SDL, you need to enable platform specific window management events, this is done as follows SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE);
After this, in the main event loop you must test for SDL_SYSWMEVENT
, which contains information about how the user has interacted with the notification area icon. This also looks for the minimize event and hides the window which removes it from the task bar. This is achieved in the following snippet
SDL_Event e;
while (SDL_PollEvent(&e) != 0)
{
switch (e.type)
{
case SDL_SYSWMEVENT:
if (e.syswm.msg->msg.win.msg == WM_USER + 1)
{
if (LOWORD(e.syswm.msg->msg.win.lParam) == WM_LBUTTONDBLCLK)
{
SDL_ShowWindow(window);
SDL_RestoreWindow(window);
}
}
break;
case SDL_QUIT:
running = false;
break;
case SDL_WINDOWEVENT:
if (e.window.event == SDL_WINDOWEVENT_MINIMIZED)
SDL_HideWindow(window);
break;
}
}