From dfdc120268e4b2875bb958fcdace54297fa73703 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sun, 19 Jan 2025 10:42:49 -0800
Subject: [PATCH] tray: document thread-safety
---
include/SDL3/SDL_tray.h | 46 ++++++++++++++++++++++++++++++++++++-
src/tray/cocoa/SDL_tray.m | 5 ++++
src/tray/unix/SDL_tray.c | 5 ++++
src/tray/windows/SDL_tray.c | 5 ++++
4 files changed, 60 insertions(+), 1 deletion(-)
diff --git a/include/SDL3/SDL_tray.h b/include/SDL3/SDL_tray.h
index b001169856de4..54123b5020342 100644
--- a/include/SDL3/SDL_tray.h
+++ b/include/SDL3/SDL_tray.h
@@ -108,6 +108,8 @@ typedef void (SDLCALL *SDL_TrayCallback)(void *userdata, SDL_TrayEntry *entry);
*
* \since This function is available since SDL 3.1.8.
*
+ * \threadsafety This function should only be called on the main thread.
+ *
* \sa SDL_CreateTrayMenu
* \sa SDL_GetTrayMenu
* \sa SDL_DestroyTray
@@ -122,6 +124,8 @@ extern SDL_DECLSPEC SDL_Tray *SDLCALL SDL_CreateTray(SDL_Surface *icon, const ch
*
* \since This function is available since SDL 3.1.8.
*
+ * \threadsafety This function should be called on the thread that created the tray.
+ *
* \sa SDL_CreateTray
*/
extern SDL_DECLSPEC void SDLCALL SDL_SetTrayIcon(SDL_Tray *tray, SDL_Surface *icon);
@@ -134,6 +138,8 @@ extern SDL_DECLSPEC void SDLCALL SDL_SetTrayIcon(SDL_Tray *tray, SDL_Surface *ic
*
* \since This function is available since SDL 3.1.8.
*
+ * \threadsafety This function should be called on the thread that created the tray.
+ *
* \sa SDL_CreateTray
*/
extern SDL_DECLSPEC void SDLCALL SDL_SetTrayTooltip(SDL_Tray *tray, const char *tooltip);
@@ -153,6 +159,8 @@ extern SDL_DECLSPEC void SDLCALL SDL_SetTrayTooltip(SDL_Tray *tray, const char *
*
* \since This function is available since SDL 3.1.8.
*
+ * \threadsafety This function should be called on the thread that created the tray.
+ *
* \sa SDL_CreateTray
* \sa SDL_GetTrayMenu
* \sa SDL_GetTrayMenuParentTray
@@ -174,6 +182,8 @@ extern SDL_DECLSPEC SDL_TrayMenu *SDLCALL SDL_CreateTrayMenu(SDL_Tray *tray);
*
* \since This function is available since SDL 3.1.8.
*
+ * \threadsafety This function should be called on the thread that created the tray.
+ *
* \sa SDL_InsertTrayEntryAt
* \sa SDL_GetTraySubmenu
* \sa SDL_GetTrayMenuParentEntry
@@ -196,6 +206,8 @@ extern SDL_DECLSPEC SDL_TrayMenu *SDLCALL SDL_CreateTraySubmenu(SDL_TrayEntry *e
*
* \since This function is available since SDL 3.1.8.
*
+ * \threadsafety This function should be called on the thread that created the tray.
+ *
* \sa SDL_CreateTray
* \sa SDL_CreateTrayMenu
*/
@@ -217,6 +229,8 @@ extern SDL_DECLSPEC SDL_TrayMenu *SDLCALL SDL_GetTrayMenu(SDL_Tray *tray);
*
* \since This function is available since SDL 3.1.8.
*
+ * \threadsafety This function should be called on the thread that created the tray.
+ *
* \sa SDL_InsertTrayEntryAt
* \sa SDL_CreateTraySubmenu
*/
@@ -234,6 +248,8 @@ extern SDL_DECLSPEC SDL_TrayMenu *SDLCALL SDL_GetTraySubmenu(SDL_TrayEntry *entr
*
* \since This function is available since SDL 3.1.8.
*
+ * \threadsafety This function should be called on the thread that created the tray.
+ *
* \sa SDL_RemoveTrayEntry
* \sa SDL_InsertTrayEntryAt
*/
@@ -246,6 +262,8 @@ extern SDL_DECLSPEC const SDL_TrayEntry **SDLCALL SDL_GetTrayEntries(SDL_TrayMen
*
* \since This function is available since SDL 3.1.8.
*
+ * \threadsafety This function should be called on the thread that created the tray.
+ *
* \sa SDL_GetTrayEntries
* \sa SDL_InsertTrayEntryAt
*/
@@ -269,6 +287,8 @@ extern SDL_DECLSPEC void SDLCALL SDL_RemoveTrayEntry(SDL_TrayEntry *entry);
*
* \since This function is available since SDL 3.1.8.
*
+ * \threadsafety This function should be called on the thread that created the tray.
+ *
* \sa SDL_TrayEntryFlags
* \sa SDL_GetTrayEntries
* \sa SDL_RemoveTrayEntry
@@ -289,6 +309,8 @@ extern SDL_DECLSPEC SDL_TrayEntry *SDLCALL SDL_InsertTrayEntryAt(SDL_TrayMenu *m
*
* \since This function is available since SDL 3.1.8.
*
+ * \threadsafety This function should be called on the thread that created the tray.
+ *
* \sa SDL_GetTrayEntries
* \sa SDL_InsertTrayEntryAt
* \sa SDL_GetTrayEntryLabel
@@ -305,6 +327,8 @@ extern SDL_DECLSPEC void SDLCALL SDL_SetTrayEntryLabel(SDL_TrayEntry *entry, con
*
* \since This function is available since SDL 3.1.8.
*
+ * \threadsafety This function should be called on the thread that created the tray.
+ *
* \sa SDL_GetTrayEntries
* \sa SDL_InsertTrayEntryAt
* \sa SDL_SetTrayEntryLabel
@@ -321,6 +345,8 @@ extern SDL_DECLSPEC const char *SDLCALL SDL_GetTrayEntryLabel(SDL_TrayEntry *ent
*
* \since This function is available since SDL 3.1.8.
*
+ * \threadsafety This function should be called on the thread that created the tray.
+ *
* \sa SDL_GetTrayEntries
* \sa SDL_InsertTrayEntryAt
* \sa SDL_GetTrayEntryChecked
@@ -337,6 +363,8 @@ extern SDL_DECLSPEC void SDLCALL SDL_SetTrayEntryChecked(SDL_TrayEntry *entry, b
*
* \since This function is available since SDL 3.1.8.
*
+ * \threadsafety This function should be called on the thread that created the tray.
+ *
* \sa SDL_GetTrayEntries
* \sa SDL_InsertTrayEntryAt
* \sa SDL_SetTrayEntryChecked
@@ -351,6 +379,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GetTrayEntryChecked(SDL_TrayEntry *entry);
*
* \since This function is available since SDL 3.1.8.
*
+ * \threadsafety This function should be called on the thread that created the tray.
+ *
* \sa SDL_GetTrayEntries
* \sa SDL_InsertTrayEntryAt
* \sa SDL_GetTrayEntryEnabled
@@ -365,6 +395,8 @@ extern SDL_DECLSPEC void SDLCALL SDL_SetTrayEntryEnabled(SDL_TrayEntry *entry, b
*
* \since This function is available since SDL 3.1.8.
*
+ * \threadsafety This function should be called on the thread that created the tray.
+ *
* \sa SDL_GetTrayEntries
* \sa SDL_InsertTrayEntryAt
* \sa SDL_SetTrayEntryEnabled
@@ -381,6 +413,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GetTrayEntryEnabled(SDL_TrayEntry *entry);
*
* \since This function is available since SDL 3.1.8.
*
+ * \threadsafety This function should be called on the thread that created the tray.
+ *
* \sa SDL_GetTrayEntries
* \sa SDL_InsertTrayEntryAt
*/
@@ -392,6 +426,8 @@ extern SDL_DECLSPEC void SDLCALL SDL_SetTrayEntryCallback(SDL_TrayEntry *entry,
* \param entry The entry to activate.
*
* \since This function is available since SDL 3.1.10.
+ *
+ * \threadsafety This function should be called on the thread that created the tray.
*/
extern SDL_DECLSPEC void SDLCALL SDL_ClickTrayEntry(SDL_TrayEntry *entry);
@@ -404,18 +440,22 @@ extern SDL_DECLSPEC void SDLCALL SDL_ClickTrayEntry(SDL_TrayEntry *entry);
*
* \since This function is available since SDL 3.1.8.
*
+ * \threadsafety This function should be called on the thread that created the tray.
+ *
* \sa SDL_CreateTray
*/
extern SDL_DECLSPEC void SDLCALL SDL_DestroyTray(SDL_Tray *tray);
/**
- * Gets the menu contianing a certain tray entry.
+ * Gets the menu containing a certain tray entry.
*
* \param entry the entry for which to get the parent menu.
* \returns the parent menu.
*
* \since This function is available since SDL 3.1.8.
*
+ * \threadsafety This function should be called on the thread that created the tray.
+ *
* \sa SDL_InsertTrayEntryAt
*/
extern SDL_DECLSPEC SDL_TrayMenu *SDLCALL SDL_GetTrayEntryParent(SDL_TrayEntry *entry);
@@ -432,6 +472,8 @@ extern SDL_DECLSPEC SDL_TrayMenu *SDLCALL SDL_GetTrayEntryParent(SDL_TrayEntry *
*
* \since This function is available since SDL 3.1.8.
*
+ * \threadsafety This function should be called on the thread that created the tray.
+ *
* \sa SDL_CreateTraySubmenu
* \sa SDL_GetTrayMenuParentTray
*/
@@ -449,6 +491,8 @@ extern SDL_DECLSPEC SDL_TrayEntry *SDLCALL SDL_GetTrayMenuParentEntry(SDL_TrayMe
*
* \since This function is available since SDL 3.1.8.
*
+ * \threadsafety This function should be called on the thread that created the tray.
+ *
* \sa SDL_CreateTrayMenu
* \sa SDL_GetTrayMenuParentEntry
*/
diff --git a/src/tray/cocoa/SDL_tray.m b/src/tray/cocoa/SDL_tray.m
index 15de54b24e9a6..9d2f55e2db347 100644
--- a/src/tray/cocoa/SDL_tray.m
+++ b/src/tray/cocoa/SDL_tray.m
@@ -80,6 +80,11 @@ static void DestroySDLMenu(SDL_TrayMenu *menu)
SDL_Tray *SDL_CreateTray(SDL_Surface *icon, const char *tooltip)
{
+ if (!SDL_IsMainThread()) {
+ SDL_SetError("This function should be called on the main thread");
+ return NULL;
+ }
+
if (icon) {
icon = SDL_ConvertSurface(icon, SDL_PIXELFORMAT_RGBA32);
if (!icon) {
diff --git a/src/tray/unix/SDL_tray.c b/src/tray/unix/SDL_tray.c
index c543ed5ba026d..c26da85a58a61 100644
--- a/src/tray/unix/SDL_tray.c
+++ b/src/tray/unix/SDL_tray.c
@@ -398,6 +398,11 @@ static void DestroySDLMenu(SDL_TrayMenu *menu)
SDL_Tray *SDL_CreateTray(SDL_Surface *icon, const char *tooltip)
{
+ if (!SDL_IsMainThread()) {
+ SDL_SetError("This function should be called on the main thread");
+ return NULL;
+ }
+
if (init_gtk() != true) {
return NULL;
}
diff --git a/src/tray/windows/SDL_tray.c b/src/tray/windows/SDL_tray.c
index dbfbabafa27a6..0afd62768f0e3 100644
--- a/src/tray/windows/SDL_tray.c
+++ b/src/tray/windows/SDL_tray.c
@@ -211,6 +211,11 @@ static HICON load_default_icon()
SDL_Tray *SDL_CreateTray(SDL_Surface *icon, const char *tooltip)
{
+ if (!SDL_IsMainThread()) {
+ SDL_SetError("This function should be called on the main thread");
+ return NULL;
+ }
+
SDL_Tray *tray = (SDL_Tray *)SDL_calloc(1, sizeof(*tray));
if (!tray) {