Added SDL_ClickTrayEntry()

Also removed the app delegate from the tray code on Cocoa and folded that into SDL3AppDelegate.

Fixes https://github.com/libsdl-org/SDL/issues/11906
This commit is contained in:
Sam Lantinga 2025-01-10 12:20:37 -08:00
parent fb0f6a1196
commit 042898995c
9 changed files with 70 additions and 31 deletions

View file

@ -388,6 +388,15 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GetTrayEntryEnabled(SDL_TrayEntry *entry);
*/ */
extern SDL_DECLSPEC void SDLCALL SDL_SetTrayEntryCallback(SDL_TrayEntry *entry, SDL_TrayCallback callback, void *userdata); extern SDL_DECLSPEC void SDLCALL SDL_SetTrayEntryCallback(SDL_TrayEntry *entry, SDL_TrayCallback callback, void *userdata);
/**
* Simulate a click on a tray entry.
*
* \param entry The entry to activate.
*
* \since This function is available since SDL 3.1.9.
*/
extern SDL_DECLSPEC void SDLCALL SDL_ClickTrayEntry(SDL_TrayEntry *entry);
/** /**
* Destroys a tray object. * Destroys a tray object.
* *

View file

@ -1231,6 +1231,7 @@ SDL3_0.0.0 {
SDL_GetTrayMenuParentTray; SDL_GetTrayMenuParentTray;
SDL_GetThreadState; SDL_GetThreadState;
SDL_AudioStreamDevicePaused; SDL_AudioStreamDevicePaused;
SDL_ClickTrayEntry;
# extra symbols go here (don't modify this line) # extra symbols go here (don't modify this line)
local: *; local: *;
}; };

View file

@ -1256,3 +1256,4 @@
#define SDL_GetTrayMenuParentTray SDL_GetTrayMenuParentTray_REAL #define SDL_GetTrayMenuParentTray SDL_GetTrayMenuParentTray_REAL
#define SDL_GetThreadState SDL_GetThreadState_REAL #define SDL_GetThreadState SDL_GetThreadState_REAL
#define SDL_AudioStreamDevicePaused SDL_AudioStreamDevicePaused_REAL #define SDL_AudioStreamDevicePaused SDL_AudioStreamDevicePaused_REAL
#define SDL_ClickTrayEntry SDL_ClickTrayEntry_REAL

View file

@ -1264,3 +1264,4 @@ SDL_DYNAPI_PROC(SDL_TrayEntry*,SDL_GetTrayMenuParentEntry,(SDL_TrayMenu *a),(a),
SDL_DYNAPI_PROC(SDL_Tray*,SDL_GetTrayMenuParentTray,(SDL_TrayMenu *a),(a),return) SDL_DYNAPI_PROC(SDL_Tray*,SDL_GetTrayMenuParentTray,(SDL_TrayMenu *a),(a),return)
SDL_DYNAPI_PROC(SDL_ThreadState,SDL_GetThreadState,(SDL_Thread *a),(a),return) SDL_DYNAPI_PROC(SDL_ThreadState,SDL_GetThreadState,(SDL_Thread *a),(a),return)
SDL_DYNAPI_PROC(bool,SDL_AudioStreamDevicePaused,(SDL_AudioStream *a),(a),return) SDL_DYNAPI_PROC(bool,SDL_AudioStreamDevicePaused,(SDL_AudioStream *a),(a),return)
SDL_DYNAPI_PROC(void,SDL_ClickTrayEntry,(SDL_TrayEntry *a),(a),)

View file

@ -58,31 +58,6 @@ struct SDL_Tray {
SDL_TrayMenu *menu; SDL_TrayMenu *menu;
}; };
static NSApplication *app = NULL;
@interface AppDelegate: NSObject <NSApplicationDelegate>
- (IBAction)menu:(id)sender;
@end
@implementation AppDelegate{}
- (IBAction)menu:(id)sender
{
SDL_TrayEntry *entry = [[sender representedObject] pointerValue];
if (!entry) {
return;
}
if (entry->flags & SDL_TRAYENTRY_CHECKBOX) {
SDL_SetTrayEntryChecked(entry, !SDL_GetTrayEntryChecked(entry));
}
if (entry->callback) {
entry->callback(entry->userdata, entry);
}
}
@end
static void DestroySDLMenu(SDL_TrayMenu *menu) static void DestroySDLMenu(SDL_TrayMenu *menu)
{ {
for (int i = 0; i < menu->nEntries; i++) { for (int i = 0; i < menu->nEntries; i++) {
@ -106,11 +81,6 @@ static void DestroySDLMenu(SDL_TrayMenu *menu)
SDL_Tray *SDL_CreateTray(SDL_Surface *icon, const char *tooltip) SDL_Tray *SDL_CreateTray(SDL_Surface *icon, const char *tooltip)
{ {
SDL_Tray *tray = (SDL_Tray *)SDL_calloc(1, sizeof(*tray)); SDL_Tray *tray = (SDL_Tray *)SDL_calloc(1, sizeof(*tray));
AppDelegate *delegate = [[AppDelegate alloc] init];
app = [NSApplication sharedApplication];
[app setDelegate:delegate];
if (!tray) { if (!tray) {
return NULL; return NULL;
} }
@ -118,7 +88,7 @@ SDL_Tray *SDL_CreateTray(SDL_Surface *icon, const char *tooltip)
tray->statusItem = nil; tray->statusItem = nil;
tray->statusBar = [NSStatusBar systemStatusBar]; tray->statusBar = [NSStatusBar systemStatusBar];
tray->statusItem = [tray->statusBar statusItemWithLength:NSVariableStatusItemLength]; tray->statusItem = [tray->statusBar statusItemWithLength:NSVariableStatusItemLength];
[app activateIgnoringOtherApps:TRUE]; [[NSApplication sharedApplication] activateIgnoringOtherApps:TRUE];
if (tooltip) { if (tooltip) {
tray->statusItem.button.toolTip = [NSString stringWithUTF8String:tooltip]; tray->statusItem.button.toolTip = [NSString stringWithUTF8String:tooltip];
@ -421,6 +391,21 @@ void SDL_SetTrayEntryCallback(SDL_TrayEntry *entry, SDL_TrayCallback callback, v
entry->userdata = userdata; entry->userdata = userdata;
} }
void SDL_ClickTrayEntry(SDL_TrayEntry *entry)
{
if (!entry) {
return;
}
if (entry->flags & SDL_TRAYENTRY_CHECKBOX) {
SDL_SetTrayEntryChecked(entry, !SDL_GetTrayEntryChecked(entry));
}
if (entry->callback) {
entry->callback(entry->userdata, entry);
}
}
SDL_TrayMenu *SDL_GetTrayEntryParent(SDL_TrayEntry *entry) SDL_TrayMenu *SDL_GetTrayEntryParent(SDL_TrayEntry *entry)
{ {
return entry->parent; return entry->parent;

View file

@ -119,6 +119,10 @@ void SDL_SetTrayEntryCallback(SDL_TrayEntry *entry, SDL_TrayCallback callback, v
SDL_Unsupported(); SDL_Unsupported();
} }
void SDL_ClickTrayEntry(SDL_TrayEntry *entry)
{
}
SDL_TrayMenu *SDL_GetTrayEntryParent(SDL_TrayEntry *entry) SDL_TrayMenu *SDL_GetTrayEntryParent(SDL_TrayEntry *entry)
{ {
SDL_Unsupported(); SDL_Unsupported();

View file

@ -671,6 +671,21 @@ void SDL_SetTrayEntryCallback(SDL_TrayEntry *entry, SDL_TrayCallback callback, v
entry->userdata = userdata; entry->userdata = userdata;
} }
void SDL_ClickTrayEntry(SDL_TrayEntry *entry)
{
if (!entry) {
return;
}
if (entry->flags & SDL_TRAYENTRY_CHECKBOX) {
SDL_SetTrayEntryChecked(entry, !SDL_GetTrayEntryChecked(entry));
}
if (entry->callback) {
entry->callback(entry->userdata, entry);
}
}
SDL_TrayMenu *SDL_GetTrayEntryParent(SDL_TrayEntry *entry) SDL_TrayMenu *SDL_GetTrayEntryParent(SDL_TrayEntry *entry)
{ {
return entry->parent; return entry->parent;

View file

@ -536,6 +536,21 @@ void SDL_SetTrayEntryCallback(SDL_TrayEntry *entry, SDL_TrayCallback callback, v
entry->userdata = userdata; entry->userdata = userdata;
} }
void SDL_ClickTrayEntry(SDL_TrayEntry *entry)
{
if (!entry) {
return;
}
if (entry->flags & SDL_TRAYENTRY_CHECKBOX) {
SDL_SetTrayEntryChecked(entry, !SDL_GetTrayEntryChecked(entry));
}
if (entry->callback) {
entry->callback(entry->userdata, entry);
}
}
SDL_TrayMenu *SDL_GetTrayEntryParent(SDL_TrayEntry *entry) SDL_TrayMenu *SDL_GetTrayEntryParent(SDL_TrayEntry *entry)
{ {
return entry->parent; return entry->parent;

View file

@ -136,6 +136,7 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent)
change:(NSDictionary *)change change:(NSDictionary *)change
context:(void *)context; context:(void *)context;
- (BOOL)applicationSupportsSecureRestorableState:(NSApplication *)app; - (BOOL)applicationSupportsSecureRestorableState:(NSApplication *)app;
- (IBAction)menu:(id)sender;
@end @end
@implementation SDL3AppDelegate : NSObject @implementation SDL3AppDelegate : NSObject
@ -358,6 +359,13 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent)
return YES; return YES;
} }
- (IBAction)menu:(id)sender
{
SDL_TrayEntry *entry = [[sender representedObject] pointerValue];
SDL_ClickTrayEntry(entry);
}
@end @end
static SDL3AppDelegate *appDelegate = nil; static SDL3AppDelegate *appDelegate = nil;