From 2568a367c82d8a509233bdb8dc2c19771a3800b0 Mon Sep 17 00:00:00 2001 From: "J?rgen P. Tjern?" Date: Mon, 7 Oct 2013 16:01:40 -0700 Subject: [PATCH] Mac: Better handling when someone else is the app delegate. --- README-macosx.txt | 36 +++++++++++++++++++++++++++++++ src/video/cocoa/SDL_cocoaevents.m | 30 +++++++++++++++++++++----- 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/README-macosx.txt b/README-macosx.txt index c5cc89b5bc8f2..021b14021d029 100644 --- a/README-macosx.txt +++ b/README-macosx.txt @@ -29,6 +29,42 @@ gcc to make this easy is provided in test/gcc-fat.sh To use the library once it's built, you essential have two possibilities: use the traditional autoconf/automake/make method, or use Xcode. +============================================================================== +Caveats for using SDL with Mac OS X +============================================================================== + +Some things you have to be aware of when using SDL on Mac OS X: + +- If you register your own NSApplicationDelegate (using [NSApp setDelegate:]), + SDL will not register its own. This means that SDL will not terminate using + SDL_Quit if it receives a termination request, it will terminate like a + normal app, and it will not send a SDL_DROPFILE when you request to open a + file with the app. To solve these issues, put the following code in your + NSApplicationDelegate implementation: + + - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender + { + if (SDL_GetEventState(SDL_QUIT) == SDL_ENABLE) { + SDL_Event event; + event.type = SDL_QUIT; + SDL_PushEvent(&event); + } + + return NSTerminateCancel; + } + + - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename + { + if (SDL_GetEventState(SDL_DROPFILE) == SDL_ENABLE) { + SDL_Event event; + event.type = SDL_DROPFILE; + event.drop.file = SDL_strdup([filename UTF8String]); + return (SDL_PushEvent(&event) > 0); + } + + return NO; + } + ============================================================================== Using the Simple DirectMedia Layer with a traditional Makefile ============================================================================== diff --git a/src/video/cocoa/SDL_cocoaevents.m b/src/video/cocoa/SDL_cocoaevents.m index 6a673c3d3a1f4..1dc0ca6252567 100644 --- a/src/video/cocoa/SDL_cocoaevents.m +++ b/src/video/cocoa/SDL_cocoaevents.m @@ -42,12 +42,11 @@ - (void)setAppleMenu:(NSMenu *)menu; @end @interface SDLAppDelegate : NSObject { +@public BOOL seenFirstActivate; } - (id)init; -- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender; -- (void)applicationDidBecomeActive:(NSNotification *)aNotification; @end @implementation SDLAppDelegate : NSObject @@ -57,18 +56,28 @@ - (id)init if (self) { seenFirstActivate = NO; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(focusSomeWindow:) + name:NSApplicationDidBecomeActiveNotification + object:nil]; } return self; } +- (void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; + [super dealloc]; +} + - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender { SDL_SendQuit(); return NSTerminateCancel; } -- (void)applicationDidBecomeActive:(NSNotification *)aNotification +- (void)focusSomeWindow:(NSNotification *)aNotification { /* HACK: Ignore the first call. The application gets a * applicationDidBecomeActive: a little bit after the first window is @@ -111,6 +120,8 @@ - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filenam } @end +static SDLAppDelegate *appDelegate = nil; + static NSString * GetApplicationName(void) { @@ -235,8 +246,17 @@ - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filenam [[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults]; } - if (NSApp && ![NSApp delegate]) { - [NSApp setDelegate:[[SDLAppDelegate alloc] init]]; + if (NSApp && !appDelegate) { + appDelegate = [[SDLAppDelegate alloc] init]; + + /* If someone else has an app delegate, it means we can't turn a + * termination into SDL_Quit, and we can't handle application:openFile: + */ + if (![NSApp delegate]) { + [NSApp setDelegate:appDelegate]; + } else { + appDelegate->seenFirstActivate = YES; + } } [pool release]; }