0





77
1

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?

Question author Colin-s | Source

0


1

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;
    }
}
Answer author Colin-s

Ask about this question here!