1 | /* |
2 | Simple DirectMedia Layer |
3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> |
4 | |
5 | This software is provided 'as-is', without any express or implied |
6 | warranty. In no event will the authors be held liable for any damages |
7 | arising from the use of this software. |
8 | |
9 | Permission is granted to anyone to use this software for any purpose, |
10 | including commercial applications, and to alter it and redistribute it |
11 | freely, subject to the following restrictions: |
12 | |
13 | 1. The origin of this software must not be misrepresented; you must not |
14 | claim that you wrote the original software. If you use this software |
15 | in a product, an acknowledgment in the product documentation would be |
16 | appreciated but is not required. |
17 | 2. Altered source versions must be plainly marked as such, and must not be |
18 | misrepresented as being the original software. |
19 | 3. This notice may not be removed or altered from any source distribution. |
20 | */ |
21 | |
22 | /** |
23 | * # CategoryTray |
24 | * |
25 | * SDL offers a way to add items to the "system tray" (more correctly called |
26 | * the "notification area" on Windows). On platforms that offer this concept, |
27 | * an SDL app can add a tray icon, submenus, checkboxes, and clickable |
28 | * entries, and register a callback that is fired when the user clicks on |
29 | * these pieces. |
30 | */ |
31 | |
32 | #ifndef SDL_tray_h_ |
33 | #define SDL_tray_h_ |
34 | |
35 | #include <SDL3/SDL_stdinc.h> |
36 | #include <SDL3/SDL_error.h> |
37 | #include <SDL3/SDL_surface.h> |
38 | #include <SDL3/SDL_video.h> |
39 | |
40 | #include <SDL3/SDL_begin_code.h> |
41 | /* Set up for C function definitions, even when using C++ */ |
42 | #ifdef __cplusplus |
43 | extern "C" { |
44 | #endif |
45 | |
46 | /** |
47 | * An opaque handle representing a toplevel system tray object. |
48 | * |
49 | * \since This struct is available since SDL 3.2.0. |
50 | */ |
51 | typedef struct SDL_Tray SDL_Tray; |
52 | |
53 | /** |
54 | * An opaque handle representing a menu/submenu on a system tray object. |
55 | * |
56 | * \since This struct is available since SDL 3.2.0. |
57 | */ |
58 | typedef struct ; |
59 | |
60 | /** |
61 | * An opaque handle representing an entry on a system tray object. |
62 | * |
63 | * \since This struct is available since SDL 3.2.0. |
64 | */ |
65 | typedef struct SDL_TrayEntry SDL_TrayEntry; |
66 | |
67 | /** |
68 | * Flags that control the creation of system tray entries. |
69 | * |
70 | * Some of these flags are required; exactly one of them must be specified at |
71 | * the time a tray entry is created. Other flags are optional; zero or more of |
72 | * those can be OR'ed together with the required flag. |
73 | * |
74 | * \since This datatype is available since SDL 3.2.0. |
75 | * |
76 | * \sa SDL_InsertTrayEntryAt |
77 | */ |
78 | typedef Uint32 SDL_TrayEntryFlags; |
79 | |
80 | #define SDL_TRAYENTRY_BUTTON 0x00000001u /**< Make the entry a simple button. Required. */ |
81 | #define SDL_TRAYENTRY_CHECKBOX 0x00000002u /**< Make the entry a checkbox. Required. */ |
82 | #define 0x00000004u /**< Prepare the entry to have a submenu. Required */ |
83 | #define SDL_TRAYENTRY_DISABLED 0x80000000u /**< Make the entry disabled. Optional. */ |
84 | #define SDL_TRAYENTRY_CHECKED 0x40000000u /**< Make the entry checked. This is valid only for checkboxes. Optional. */ |
85 | |
86 | /** |
87 | * A callback that is invoked when a tray entry is selected. |
88 | * |
89 | * \param userdata an optional pointer to pass extra data to the callback when |
90 | * it will be invoked. |
91 | * \param entry the tray entry that was selected. |
92 | * |
93 | * \since This datatype is available since SDL 3.2.0. |
94 | * |
95 | * \sa SDL_SetTrayEntryCallback |
96 | */ |
97 | typedef void (SDLCALL *SDL_TrayCallback)(void *userdata, SDL_TrayEntry *entry); |
98 | |
99 | /** |
100 | * Create an icon to be placed in the operating system's tray, or equivalent. |
101 | * |
102 | * Many platforms advise not using a system tray unless persistence is a |
103 | * necessary feature. Avoid needlessly creating a tray icon, as the user may |
104 | * feel like it clutters their interface. |
105 | * |
106 | * Using tray icons require the video subsystem. |
107 | * |
108 | * \param icon a surface to be used as icon. May be NULL. |
109 | * \param tooltip a tooltip to be displayed when the mouse hovers the icon in |
110 | * UTF-8 encoding. Not supported on all platforms. May be NULL. |
111 | * \returns The newly created system tray icon. |
112 | * |
113 | * \threadsafety This function should only be called on the main thread. |
114 | * |
115 | * \since This function is available since SDL 3.2.0. |
116 | * |
117 | * \sa SDL_CreateTrayMenu |
118 | * \sa SDL_GetTrayMenu |
119 | * \sa SDL_DestroyTray |
120 | */ |
121 | extern SDL_DECLSPEC SDL_Tray * SDLCALL SDL_CreateTray(SDL_Surface *icon, const char *tooltip); |
122 | |
123 | /** |
124 | * Updates the system tray icon's icon. |
125 | * |
126 | * \param tray the tray icon to be updated. |
127 | * \param icon the new icon. May be NULL. |
128 | * |
129 | * \threadsafety This function should be called on the thread that created the |
130 | * tray. |
131 | * |
132 | * \since This function is available since SDL 3.2.0. |
133 | * |
134 | * \sa SDL_CreateTray |
135 | */ |
136 | extern SDL_DECLSPEC void SDLCALL SDL_SetTrayIcon(SDL_Tray *tray, SDL_Surface *icon); |
137 | |
138 | /** |
139 | * Updates the system tray icon's tooltip. |
140 | * |
141 | * \param tray the tray icon to be updated. |
142 | * \param tooltip the new tooltip in UTF-8 encoding. May be NULL. |
143 | * |
144 | * \threadsafety This function should be called on the thread that created the |
145 | * tray. |
146 | * |
147 | * \since This function is available since SDL 3.2.0. |
148 | * |
149 | * \sa SDL_CreateTray |
150 | */ |
151 | extern SDL_DECLSPEC void SDLCALL SDL_SetTrayTooltip(SDL_Tray *tray, const char *tooltip); |
152 | |
153 | /** |
154 | * Create a menu for a system tray. |
155 | * |
156 | * This should be called at most once per tray icon. |
157 | * |
158 | * This function does the same thing as SDL_CreateTraySubmenu(), except that |
159 | * it takes a SDL_Tray instead of a SDL_TrayEntry. |
160 | * |
161 | * A menu does not need to be destroyed; it will be destroyed with the tray. |
162 | * |
163 | * \param tray the tray to bind the menu to. |
164 | * \returns the newly created menu. |
165 | * |
166 | * \threadsafety This function should be called on the thread that created the |
167 | * tray. |
168 | * |
169 | * \since This function is available since SDL 3.2.0. |
170 | * |
171 | * \sa SDL_CreateTray |
172 | * \sa SDL_GetTrayMenu |
173 | * \sa SDL_GetTrayMenuParentTray |
174 | */ |
175 | extern SDL_DECLSPEC SDL_TrayMenu * SDLCALL SDL_CreateTrayMenu(SDL_Tray *tray); |
176 | |
177 | /** |
178 | * Create a submenu for a system tray entry. |
179 | * |
180 | * This should be called at most once per tray entry. |
181 | * |
182 | * This function does the same thing as SDL_CreateTrayMenu, except that it |
183 | * takes a SDL_TrayEntry instead of a SDL_Tray. |
184 | * |
185 | * A menu does not need to be destroyed; it will be destroyed with the tray. |
186 | * |
187 | * \param entry the tray entry to bind the menu to. |
188 | * \returns the newly created menu. |
189 | * |
190 | * \threadsafety This function should be called on the thread that created the |
191 | * tray. |
192 | * |
193 | * \since This function is available since SDL 3.2.0. |
194 | * |
195 | * \sa SDL_InsertTrayEntryAt |
196 | * \sa SDL_GetTraySubmenu |
197 | * \sa SDL_GetTrayMenuParentEntry |
198 | */ |
199 | extern SDL_DECLSPEC SDL_TrayMenu * SDLCALL SDL_CreateTraySubmenu(SDL_TrayEntry *entry); |
200 | |
201 | /** |
202 | * Gets a previously created tray menu. |
203 | * |
204 | * You should have called SDL_CreateTrayMenu() on the tray object. This |
205 | * function allows you to fetch it again later. |
206 | * |
207 | * This function does the same thing as SDL_GetTraySubmenu(), except that it |
208 | * takes a SDL_Tray instead of a SDL_TrayEntry. |
209 | * |
210 | * A menu does not need to be destroyed; it will be destroyed with the tray. |
211 | * |
212 | * \param tray the tray entry to bind the menu to. |
213 | * \returns the newly created menu. |
214 | * |
215 | * \threadsafety This function should be called on the thread that created the |
216 | * tray. |
217 | * |
218 | * \since This function is available since SDL 3.2.0. |
219 | * |
220 | * \sa SDL_CreateTray |
221 | * \sa SDL_CreateTrayMenu |
222 | */ |
223 | extern SDL_DECLSPEC SDL_TrayMenu * SDLCALL SDL_GetTrayMenu(SDL_Tray *tray); |
224 | |
225 | /** |
226 | * Gets a previously created tray entry submenu. |
227 | * |
228 | * You should have called SDL_CreateTraySubmenu() on the entry object. This |
229 | * function allows you to fetch it again later. |
230 | * |
231 | * This function does the same thing as SDL_GetTrayMenu(), except that it |
232 | * takes a SDL_TrayEntry instead of a SDL_Tray. |
233 | * |
234 | * A menu does not need to be destroyed; it will be destroyed with the tray. |
235 | * |
236 | * \param entry the tray entry to bind the menu to. |
237 | * \returns the newly created menu. |
238 | * |
239 | * \threadsafety This function should be called on the thread that created the |
240 | * tray. |
241 | * |
242 | * \since This function is available since SDL 3.2.0. |
243 | * |
244 | * \sa SDL_InsertTrayEntryAt |
245 | * \sa SDL_CreateTraySubmenu |
246 | */ |
247 | extern SDL_DECLSPEC SDL_TrayMenu * SDLCALL SDL_GetTraySubmenu(SDL_TrayEntry *entry); |
248 | |
249 | /** |
250 | * Returns a list of entries in the menu, in order. |
251 | * |
252 | * \param menu The menu to get entries from. |
253 | * \param count An optional pointer to obtain the number of entries in the |
254 | * menu. |
255 | * \returns a NULL-terminated list of entries within the given menu. The |
256 | * pointer becomes invalid when any function that inserts or deletes |
257 | * entries in the menu is called. |
258 | * |
259 | * \threadsafety This function should be called on the thread that created the |
260 | * tray. |
261 | * |
262 | * \since This function is available since SDL 3.2.0. |
263 | * |
264 | * \sa SDL_RemoveTrayEntry |
265 | * \sa SDL_InsertTrayEntryAt |
266 | */ |
267 | extern SDL_DECLSPEC const SDL_TrayEntry ** SDLCALL SDL_GetTrayEntries(SDL_TrayMenu *, int *count); |
268 | |
269 | /** |
270 | * Removes a tray entry. |
271 | * |
272 | * \param entry The entry to be deleted. |
273 | * |
274 | * \threadsafety This function should be called on the thread that created the |
275 | * tray. |
276 | * |
277 | * \since This function is available since SDL 3.2.0. |
278 | * |
279 | * \sa SDL_GetTrayEntries |
280 | * \sa SDL_InsertTrayEntryAt |
281 | */ |
282 | extern SDL_DECLSPEC void SDLCALL SDL_RemoveTrayEntry(SDL_TrayEntry *entry); |
283 | |
284 | /** |
285 | * Insert a tray entry at a given position. |
286 | * |
287 | * If label is NULL, the entry will be a separator. Many functions won't work |
288 | * for an entry that is a separator. |
289 | * |
290 | * An entry does not need to be destroyed; it will be destroyed with the tray. |
291 | * |
292 | * \param menu the menu to append the entry to. |
293 | * \param pos the desired position for the new entry. Entries at or following |
294 | * this place will be moved. If pos is -1, the entry is appended. |
295 | * \param label the text to be displayed on the entry, in UTF-8 encoding, or |
296 | * NULL for a separator. |
297 | * \param flags a combination of flags, some of which are mandatory. |
298 | * \returns the newly created entry, or NULL if pos is out of bounds. |
299 | * |
300 | * \threadsafety This function should be called on the thread that created the |
301 | * tray. |
302 | * |
303 | * \since This function is available since SDL 3.2.0. |
304 | * |
305 | * \sa SDL_TrayEntryFlags |
306 | * \sa SDL_GetTrayEntries |
307 | * \sa SDL_RemoveTrayEntry |
308 | * \sa SDL_GetTrayEntryParent |
309 | */ |
310 | extern SDL_DECLSPEC SDL_TrayEntry * SDLCALL SDL_InsertTrayEntryAt(SDL_TrayMenu *, int pos, const char *label, SDL_TrayEntryFlags flags); |
311 | |
312 | /** |
313 | * Sets the label of an entry. |
314 | * |
315 | * An entry cannot change between a separator and an ordinary entry; that is, |
316 | * it is not possible to set a non-NULL label on an entry that has a NULL |
317 | * label (separators), or to set a NULL label to an entry that has a non-NULL |
318 | * label. The function will silently fail if that happens. |
319 | * |
320 | * \param entry the entry to be updated. |
321 | * \param label the new label for the entry in UTF-8 encoding. |
322 | * |
323 | * \threadsafety This function should be called on the thread that created the |
324 | * tray. |
325 | * |
326 | * \since This function is available since SDL 3.2.0. |
327 | * |
328 | * \sa SDL_GetTrayEntries |
329 | * \sa SDL_InsertTrayEntryAt |
330 | * \sa SDL_GetTrayEntryLabel |
331 | */ |
332 | extern SDL_DECLSPEC void SDLCALL SDL_SetTrayEntryLabel(SDL_TrayEntry *entry, const char *label); |
333 | |
334 | /** |
335 | * Gets the label of an entry. |
336 | * |
337 | * If the returned value is NULL, the entry is a separator. |
338 | * |
339 | * \param entry the entry to be read. |
340 | * \returns the label of the entry in UTF-8 encoding. |
341 | * |
342 | * \threadsafety This function should be called on the thread that created the |
343 | * tray. |
344 | * |
345 | * \since This function is available since SDL 3.2.0. |
346 | * |
347 | * \sa SDL_GetTrayEntries |
348 | * \sa SDL_InsertTrayEntryAt |
349 | * \sa SDL_SetTrayEntryLabel |
350 | */ |
351 | extern SDL_DECLSPEC const char * SDLCALL SDL_GetTrayEntryLabel(SDL_TrayEntry *entry); |
352 | |
353 | /** |
354 | * Sets whether or not an entry is checked. |
355 | * |
356 | * The entry must have been created with the SDL_TRAYENTRY_CHECKBOX flag. |
357 | * |
358 | * \param entry the entry to be updated. |
359 | * \param checked true if the entry should be checked; false otherwise. |
360 | * |
361 | * \threadsafety This function should be called on the thread that created the |
362 | * tray. |
363 | * |
364 | * \since This function is available since SDL 3.2.0. |
365 | * |
366 | * \sa SDL_GetTrayEntries |
367 | * \sa SDL_InsertTrayEntryAt |
368 | * \sa SDL_GetTrayEntryChecked |
369 | */ |
370 | extern SDL_DECLSPEC void SDLCALL SDL_SetTrayEntryChecked(SDL_TrayEntry *entry, bool checked); |
371 | |
372 | /** |
373 | * Gets whether or not an entry is checked. |
374 | * |
375 | * The entry must have been created with the SDL_TRAYENTRY_CHECKBOX flag. |
376 | * |
377 | * \param entry the entry to be read. |
378 | * \returns true if the entry is checked; false otherwise. |
379 | * |
380 | * \threadsafety This function should be called on the thread that created the |
381 | * tray. |
382 | * |
383 | * \since This function is available since SDL 3.2.0. |
384 | * |
385 | * \sa SDL_GetTrayEntries |
386 | * \sa SDL_InsertTrayEntryAt |
387 | * \sa SDL_SetTrayEntryChecked |
388 | */ |
389 | extern SDL_DECLSPEC bool SDLCALL SDL_GetTrayEntryChecked(SDL_TrayEntry *entry); |
390 | |
391 | /** |
392 | * Sets whether or not an entry is enabled. |
393 | * |
394 | * \param entry the entry to be updated. |
395 | * \param enabled true if the entry should be enabled; false otherwise. |
396 | * |
397 | * \threadsafety This function should be called on the thread that created the |
398 | * tray. |
399 | * |
400 | * \since This function is available since SDL 3.2.0. |
401 | * |
402 | * \sa SDL_GetTrayEntries |
403 | * \sa SDL_InsertTrayEntryAt |
404 | * \sa SDL_GetTrayEntryEnabled |
405 | */ |
406 | extern SDL_DECLSPEC void SDLCALL SDL_SetTrayEntryEnabled(SDL_TrayEntry *entry, bool enabled); |
407 | |
408 | /** |
409 | * Gets whether or not an entry is enabled. |
410 | * |
411 | * \param entry the entry to be read. |
412 | * \returns true if the entry is enabled; false otherwise. |
413 | * |
414 | * \threadsafety This function should be called on the thread that created the |
415 | * tray. |
416 | * |
417 | * \since This function is available since SDL 3.2.0. |
418 | * |
419 | * \sa SDL_GetTrayEntries |
420 | * \sa SDL_InsertTrayEntryAt |
421 | * \sa SDL_SetTrayEntryEnabled |
422 | */ |
423 | extern SDL_DECLSPEC bool SDLCALL SDL_GetTrayEntryEnabled(SDL_TrayEntry *entry); |
424 | |
425 | /** |
426 | * Sets a callback to be invoked when the entry is selected. |
427 | * |
428 | * \param entry the entry to be updated. |
429 | * \param callback a callback to be invoked when the entry is selected. |
430 | * \param userdata an optional pointer to pass extra data to the callback when |
431 | * it will be invoked. |
432 | * |
433 | * \threadsafety This function should be called on the thread that created the |
434 | * tray. |
435 | * |
436 | * \since This function is available since SDL 3.2.0. |
437 | * |
438 | * \sa SDL_GetTrayEntries |
439 | * \sa SDL_InsertTrayEntryAt |
440 | */ |
441 | extern SDL_DECLSPEC void SDLCALL SDL_SetTrayEntryCallback(SDL_TrayEntry *entry, SDL_TrayCallback callback, void *userdata); |
442 | |
443 | /** |
444 | * Simulate a click on a tray entry. |
445 | * |
446 | * \param entry The entry to activate. |
447 | * |
448 | * \threadsafety This function should be called on the thread that created the |
449 | * tray. |
450 | * |
451 | * \since This function is available since SDL 3.2.0. |
452 | */ |
453 | extern SDL_DECLSPEC void SDLCALL SDL_ClickTrayEntry(SDL_TrayEntry *entry); |
454 | |
455 | /** |
456 | * Destroys a tray object. |
457 | * |
458 | * This also destroys all associated menus and entries. |
459 | * |
460 | * \param tray the tray icon to be destroyed. |
461 | * |
462 | * \threadsafety This function should be called on the thread that created the |
463 | * tray. |
464 | * |
465 | * \since This function is available since SDL 3.2.0. |
466 | * |
467 | * \sa SDL_CreateTray |
468 | */ |
469 | extern SDL_DECLSPEC void SDLCALL SDL_DestroyTray(SDL_Tray *tray); |
470 | |
471 | /** |
472 | * Gets the menu containing a certain tray entry. |
473 | * |
474 | * \param entry the entry for which to get the parent menu. |
475 | * \returns the parent menu. |
476 | * |
477 | * \threadsafety This function should be called on the thread that created the |
478 | * tray. |
479 | * |
480 | * \since This function is available since SDL 3.2.0. |
481 | * |
482 | * \sa SDL_InsertTrayEntryAt |
483 | */ |
484 | extern SDL_DECLSPEC SDL_TrayMenu * SDLCALL SDL_GetTrayEntryParent(SDL_TrayEntry *entry); |
485 | |
486 | /** |
487 | * Gets the entry for which the menu is a submenu, if the current menu is a |
488 | * submenu. |
489 | * |
490 | * Either this function or SDL_GetTrayMenuParentTray() will return non-NULL |
491 | * for any given menu. |
492 | * |
493 | * \param menu the menu for which to get the parent entry. |
494 | * \returns the parent entry, or NULL if this menu is not a submenu. |
495 | * |
496 | * \threadsafety This function should be called on the thread that created the |
497 | * tray. |
498 | * |
499 | * \since This function is available since SDL 3.2.0. |
500 | * |
501 | * \sa SDL_CreateTraySubmenu |
502 | * \sa SDL_GetTrayMenuParentTray |
503 | */ |
504 | extern SDL_DECLSPEC SDL_TrayEntry * SDLCALL SDL_GetTrayMenuParentEntry(SDL_TrayMenu *); |
505 | |
506 | /** |
507 | * Gets the tray for which this menu is the first-level menu, if the current |
508 | * menu isn't a submenu. |
509 | * |
510 | * Either this function or SDL_GetTrayMenuParentEntry() will return non-NULL |
511 | * for any given menu. |
512 | * |
513 | * \param menu the menu for which to get the parent enttrayry. |
514 | * \returns the parent tray, or NULL if this menu is a submenu. |
515 | * |
516 | * \threadsafety This function should be called on the thread that created the |
517 | * tray. |
518 | * |
519 | * \since This function is available since SDL 3.2.0. |
520 | * |
521 | * \sa SDL_CreateTrayMenu |
522 | * \sa SDL_GetTrayMenuParentEntry |
523 | */ |
524 | extern SDL_DECLSPEC SDL_Tray * SDLCALL SDL_GetTrayMenuParentTray(SDL_TrayMenu *); |
525 | |
526 | /** |
527 | * Update the trays. |
528 | * |
529 | * This is called automatically by the event loop and is only needed if you're |
530 | * using trays but aren't handling SDL events. |
531 | * |
532 | * \threadsafety This function should only be called on the main thread. |
533 | * |
534 | * \since This function is available since SDL 3.2.0. |
535 | */ |
536 | extern SDL_DECLSPEC void SDLCALL SDL_UpdateTrays(void); |
537 | |
538 | /* Ends C function definitions when using C++ */ |
539 | #ifdef __cplusplus |
540 | } |
541 | #endif |
542 | #include <SDL3/SDL_close_code.h> |
543 | |
544 | #endif /* SDL_tray_h_ */ |
545 | |