Skip to content

Add progress bar support for Windows #12530

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Mar 22, 2025
Merged

Conversation

RT2Code
Copy link
Contributor

@RT2Code RT2Code commented Mar 12, 2025

Add support for taskbar icon progress bars on the Windows platform.

Description

This PR is based on the discussion in #7901 and adds two functions:

bool SDL_SetWindowProgressState(SDL_Window *window, SDL_ProgressState state);
bool SDL_SetWindowProgressValue(SDL_Window *window, float value);

These functions can be used to set the progress state of any window. There is 5 progress states available:

Progress state Apparence (Windows 11)
SDL_PROGRESS_STATE_NONE none
SDL_PROGRESS_STATE_UNDETERMINATE undeterminate
SDL_PROGRESS_STATE_NORMAL normal
SDL_PROGRESS_STATE_PAUSED paused
SDL_PROGRESS_STATE_ERROR error

The bar value can be changed with SDL_SetWindowProgressValue (0.0f is 0% and 1.0f is 100%) on the following states:
SDL_PROGRESS_STATE_NORMAL, SDL_PROGRESS_STATE_PAUSED and SDL_PROGRESS_STATE_ERROR

Progress bars are also available on macOS and Linux. Unfortunately, I cannot provide an implementation for these platforms, as I do not use them. Some may argue that certain progress states are only available on Windows, but I believe it is still beneficial to provide them, as it would be easy to fall back on alternative states for platforms where they are not supported.

Please note that these functions require at least Windows 7 to work, as ITaskList3 isn't avaible on earlier versions. I tried to follow the SDL way of doing things as closely as possible, but I'm unsure of the best method to check whether this interface is available. I opted to check for the availability of shobjidl_core.h, but it might be better to use Windows version macros.

You may wonder why the ITaskList3 is initialized from a message in the window proc. According to the documentation, that's how it should be done:

When an application displays a window, its taskbar button is created by the system. When the button is in place, the taskbar sends a TaskbarButtonCreated message to the window. Your application should call RegisterWindowMessage(L"TaskbarButtonCreated") and handle that message in its wndproc. That message must be received by your application before it calls any ITaskbarList3 method.

The call to ITaskList3::HrInit is also required to use ITaskList3 methods.

Existing Issue(s)

Fix #7901

@slouken slouken added this to the 3.4.0 milestone Mar 12, 2025
@slouken
Copy link
Collaborator

slouken commented Mar 12, 2025

@Semphriss, you might be interested in this.

@Semphriss
Copy link
Contributor

@Semphriss, you might be interested in this.

Thanks!

I'll see if I can take care of the macOS and Unix DE implementations shortly.


[...] it would be easy to fall back on alternative states for platforms where they are not supported.

Did you have a specific fallback graph in mind? (Which state to use when one isn't available on a certain platform)

The API looks good to me, I haven't read the implementation fully but that should be easily changeable later, if necessary.

@RT2Code
Copy link
Contributor Author

RT2Code commented Mar 12, 2025

Did you have a specific fallback graph in mind? (Which state to use when one isn't available on a certain platform)

Yes, all platforms that support progress bars will provide a NORMAL state, as it is the most basic. For PAUSE and ERROR, it's simple: just fall back to NORMAL, because the most important thing here is the progress value; the bar's color is merely an additional layer of information. For INDETERMINATE, I believe falling back to NONE is best, because this state has no inherent value, and falling back to NORMAL could display the previously set value, which would be irrelevant.

@slouken slouken merged commit 7a10fcd into libsdl-org:main Mar 22, 2025
39 checks passed
@slouken
Copy link
Collaborator

slouken commented Mar 22, 2025

Looks good, thanks!

@GamesTrap
Copy link
Contributor

@Semphriss, you could use my PR over at glfw as a reference for a Linux (Unity/LauncherAPI) and macOS (NSProgressIndicator) implementation.

@slouken
Copy link
Collaborator

slouken commented May 6, 2025

@GamesTrap, would you mind creating an SDL PR?

@Semphriss
Copy link
Contributor

@GamesTrap I would be inclined to leave it to you if at all possible, given that the little amount of free time I have for SDL is passed trying to understand DBus to make the AppIndicator-free Unix tray implementation.

@GamesTrap
Copy link
Contributor

@GamesTrap, would you mind creating an SDL PR?

@GamesTrap I would be inclined to leave it to you if at all possible, given that the little amount of free time I have for SDL is passed trying to understand DBus to make the AppIndicator-free Unix tray implementation.

See #12976 :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Feature Request] Add update progress bar ?
4 participants