diff --git a/include/SDL3/SDL_tray.h b/include/SDL3/SDL_tray.h index 1780b0ba52bb7..ce8c05224ce76 100644 --- a/include/SDL3/SDL_tray.h +++ b/include/SDL3/SDL_tray.h @@ -96,6 +96,27 @@ typedef Uint32 SDL_TrayEntryFlags; */ typedef void (SDLCALL *SDL_TrayCallback)(void *userdata, SDL_TrayEntry *entry); +/** + * Check whether or not tray icons can be created. + * + * Note that this function does not guarantee that SDL_CreateTray() will or will + * not work; you should still check SDL_CreateTray() for errors. Also, the + * availability of trays may change while the program is running, for example + * if the user installs or uninstalls a relevant system library. + * + * Using tray icons require the video subsystem. + * + * \returns true if trays are available, false otherwise. + * + * \threadsafety This function should only be called on the main thread. It will + * return false if not called on the main thread. + * + * \since This function is available since SDL 3.4.0. + * + * \sa SDL_CreateTray + */ +extern SDL_DECLSPEC bool SDLCALL SDL_IsTraySupported(void); + /** * Create an icon to be placed in the operating system's tray, or equivalent. * diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym index a3e47763ea072..bd9bdb8e8262c 100644 --- a/src/dynapi/SDL_dynapi.sym +++ b/src/dynapi/SDL_dynapi.sym @@ -1253,6 +1253,7 @@ SDL3_0.0.0 { SDL_PutAudioStreamPlanarData; SDL_SetAudioIterationCallbacks; SDL_GetEventDescription; + SDL_IsTraySupported; # extra symbols go here (don't modify this line) local: *; }; diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index 4242dab7e97b8..94079f4c4cfb3 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -1278,3 +1278,4 @@ #define SDL_PutAudioStreamPlanarData SDL_PutAudioStreamPlanarData_REAL #define SDL_SetAudioIterationCallbacks SDL_SetAudioIterationCallbacks_REAL #define SDL_GetEventDescription SDL_GetEventDescription_REAL +#define SDL_IsTraySupported SDL_IsTraySupported_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index 49187b03292fe..b4f3c22b2dbbb 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -1286,3 +1286,4 @@ SDL_DYNAPI_PROC(SDL_Renderer*,SDL_CreateGPURenderer,(SDL_Window *a,SDL_GPUShader SDL_DYNAPI_PROC(bool,SDL_PutAudioStreamPlanarData,(SDL_AudioStream *a,const void * const*b,int c,int d),(a,b,c,d),return) SDL_DYNAPI_PROC(bool,SDL_SetAudioIterationCallbacks,(SDL_AudioDeviceID a,SDL_AudioIterationCallback b,SDL_AudioIterationCallback c,void *d),(a,b,c,d),return) SDL_DYNAPI_PROC(int,SDL_GetEventDescription,(const SDL_Event *a,char *b,int c),(a,b,c),return) +SDL_DYNAPI_PROC(bool,SDL_IsTraySupported,(void),(),return) diff --git a/src/tray/cocoa/SDL_tray.m b/src/tray/cocoa/SDL_tray.m index fd7f95517c2da..d093972a2d2c6 100644 --- a/src/tray/cocoa/SDL_tray.m +++ b/src/tray/cocoa/SDL_tray.m @@ -82,6 +82,16 @@ void SDL_UpdateTrays(void) { } +bool SDL_IsTraySupported(void) +{ + if (!SDL_IsMainThread()) { + SDL_SetError("This function should be called on the main thread"); + return false; + } + + return true; +} + SDL_Tray *SDL_CreateTray(SDL_Surface *icon, const char *tooltip) { if (!SDL_IsMainThread()) { diff --git a/src/tray/dummy/SDL_tray.c b/src/tray/dummy/SDL_tray.c index 766fb92584ef9..3a95c6575bd89 100644 --- a/src/tray/dummy/SDL_tray.c +++ b/src/tray/dummy/SDL_tray.c @@ -29,6 +29,11 @@ void SDL_UpdateTrays(void) { } +bool SDL_IsTraySupported(void) +{ + return false; +} + SDL_Tray *SDL_CreateTray(SDL_Surface *icon, const char *tooltip) { SDL_Unsupported(); diff --git a/src/tray/unix/SDL_tray.c b/src/tray/unix/SDL_tray.c index e8a7b0d7ee13e..174c65456c6b2 100644 --- a/src/tray/unix/SDL_tray.c +++ b/src/tray/unix/SDL_tray.c @@ -413,6 +413,16 @@ void SDL_UpdateTrays(void) } } +bool SDL_IsTraySupported(void) +{ + if (!SDL_IsMainThread()) { + SDL_SetError("This function should be called on the main thread"); + return false; + } + + return init_gtk(); +} + SDL_Tray *SDL_CreateTray(SDL_Surface *icon, const char *tooltip) { if (!SDL_IsMainThread()) { diff --git a/src/tray/windows/SDL_tray.c b/src/tray/windows/SDL_tray.c index 15021ac79845c..a3bd81ff10f03 100644 --- a/src/tray/windows/SDL_tray.c +++ b/src/tray/windows/SDL_tray.c @@ -216,6 +216,16 @@ void SDL_UpdateTrays(void) { } +bool SDL_IsTraySupported(void) +{ + if (!SDL_IsMainThread()) { + SDL_SetError("This function should be called on the main thread"); + return false; + } + + return true; +} + SDL_Tray *SDL_CreateTray(SDL_Surface *icon, const char *tooltip) { if (!SDL_IsMainThread()) {