Skip to content
Permalink
Browse files

Mac: Better handling when someone else is the app delegate.

  • Loading branch information
jorgenpt committed Oct 7, 2013
1 parent 69e1e77 commit 2568a367c82d8a509233bdb8dc2c19771a3800b0
Showing with 61 additions and 5 deletions.
  1. +36 −0 README-macosx.txt
  2. +25 −5 src/video/cocoa/SDL_cocoaevents.m
@@ -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
==============================================================================
@@ -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];
}

0 comments on commit 2568a36

Please sign in to comment.