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