Skip to content

Commit

Permalink
Date: Thu, 2 Sep 2004 19:35:51 +0200
Browse files Browse the repository at this point in the history
From: Max Horn
Subject: [Patch]: Improved menu code for SDLMain.m

the attached patch improves the menu setup for SDL apps built without a
.nib file. On 10.3, the application menus are empty with the current
SDL CVS version; after this patch, a proper app & window menu, with
"About", "Hide", "Quit", "Minimize" etc. entries are visible, just like
with the .nib enabled applications.

This *should* work on 10.2 and even 10.1, but I can't guarantee it, so
somebody should test there, ideally.

I also changed the way setupWorkingDirectory works by making use of the
Bundle APIs, that results in (IMO) less hackish code.

Finally, I added some "static" keywords to ensure that certain local
functions are not exported (that's just a paranoia change, I guess:
never pollute linker namespaces if you can avoid it).
  • Loading branch information
slouken committed Sep 17, 2004
1 parent ac4333f commit c303287
Showing 1 changed file with 71 additions and 55 deletions.
126 changes: 71 additions & 55 deletions src/main/macosx/SDLMain.m
Expand Up @@ -33,16 +33,27 @@
static char **gArgv;
static BOOL gFinderLaunch;

static NSString *getApplicationName(void)
{
NSDictionary *dict;
NSString *appName = 0;

/* Determine the application name */
dict = (NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle());
if (dict)
appName = [dict objectForKey: @"CFBundleName"];

if (![appName length])
appName = [[NSProcessInfo processInfo] processName];

return appName;
}

#if SDL_USE_NIB_FILE
/* A helper category for NSString */
@interface NSString (ReplaceSubString)
- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString;
@end
#else
/* An internal Apple class used to setup Apple menus */
@interface NSAppleMenuController:NSObject {}
- (void)controlMenu:(NSMenu *)aMenu;
@end
#endif

@interface SDLApplication : NSApplication
Expand All @@ -59,33 +70,24 @@ - (void)terminate:(id)sender
}
@end


/* The main class of the application, the application's delegate */
@implementation SDLMain

/* Set the working directory to the .app's parent directory */
- (void) setupWorkingDirectory:(BOOL)shouldChdir
{

if (shouldChdir)
{
char parentdir[MAXPATHLEN];
char *c;

strncpy ( parentdir, gArgv[0], sizeof(parentdir) );
c = (char*) parentdir;

while (*c != '\0') /* go to end */
c++;

while (*c != '/') /* back up to parent */
c--;
CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle());
CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url);
if (CFURLGetFileSystemRepresentation(url2, true, parentdir, MAXPATHLEN)) {
assert ( chdir (parentdir) == 0 ); /* chdir to the binary app's parent */
}
CFRelease(url);
CFRelease(url2);
}

*c++ = '\0'; /* cut off last part (binary name) */

assert ( chdir (parentdir) == 0 ); /* chdir to the binary app's parent */
assert ( chdir ("../../../") == 0 ); /* chdir to the .app's parent */
}
}

#if SDL_USE_NIB_FILE
Expand Down Expand Up @@ -115,38 +117,56 @@ - (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName

#else

void setupAppleMenu(void)
static void setApplicationMenu(void)
{
/* warning: this code is very odd */
NSAppleMenuController *appleMenuController;
NSMenu *appleMenu;
NSMenuItem *appleMenuItem;

appleMenuController = [[NSAppleMenuController alloc] init];
NSMenuItem *menuItem;
NSString *title;
NSString *appName;

appName = getApplicationName();
appleMenu = [[NSMenu alloc] initWithTitle:@""];
appleMenuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];

[appleMenuItem setSubmenu:appleMenu];

/* yes, we do need to add it and then remove it --
if you don't add it, it doesn't get displayed
if you don't remove it, you have an extra, titleless item in the menubar
when you remove it, it appears to stick around
very, very odd */
[[NSApp mainMenu] addItem:appleMenuItem];
[appleMenuController controlMenu:appleMenu];
[[NSApp mainMenu] removeItem:appleMenuItem];
/* Add menu items */
title = [@"About " stringByAppendingString:appName];
[appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];

[appleMenu addItem:[NSMenuItem separatorItem]];

title = [@"Hide " stringByAppendingString:appName];
[appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"];

menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
[menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];

[appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];

[appleMenu addItem:[NSMenuItem separatorItem]];

title = [@"Quit " stringByAppendingString:appName];
[appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];


/* Put menu into the menubar */
menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
[menuItem setSubmenu:appleMenu];
[[NSApp mainMenu] addItem:menuItem];

/* Tell the application object that this is now the application menu */
[NSApp setAppleMenu:appleMenu];

/* Finally give up our references to the objects */
[appleMenu release];
[appleMenuItem release];
[menuItem release];
}

/* Create a window menu */
void setupWindowMenu(void)
static void setupWindowMenu(void)
{
NSMenu *windowMenu;
NSMenuItem *windowMenuItem;
NSMenuItem *menuItem;

NSMenu *windowMenu;
NSMenuItem *windowMenuItem;
NSMenuItem *menuItem;

windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];

Expand All @@ -169,7 +189,7 @@ void setupWindowMenu(void)
}

/* Replacement for NSApplicationMain */
void CustomApplicationMain (argc, argv)
static void CustomApplicationMain (argc, argv)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
SDLMain *sdlMain;
Expand All @@ -190,9 +210,9 @@ void CustomApplicationMain (argc, argv)

/* Set up the menubar */
[NSApp setMainMenu:[[NSMenu alloc] init]];
setupAppleMenu();
setApplicationMenu();
setupWindowMenu();

/* Create SDLMain and make it the app delegate */
sdlMain = [[SDLMain alloc] init];
[NSApp setDelegate:sdlMain];
Expand All @@ -216,7 +236,7 @@ - (void) applicationDidFinishLaunching: (NSNotification *) note

#if SDL_USE_NIB_FILE
/* Set the main menu to contain the real app name instead of "SDL App" */
[self fixMenu:[NSApp mainMenu] withAppName:[[NSProcessInfo processInfo] processName]];
[self fixMenu:[NSApp mainMenu] withAppName:getApplicationName()];
#endif

/* Hand off to main application code */
Expand Down Expand Up @@ -284,16 +304,12 @@ int main (int argc, char **argv)
/* This is passed if we are launched by double-clicking */
if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) {
gArgc = 1;
gFinderLaunch = YES;
gFinderLaunch = YES;
} else {
gArgc = argc;
gFinderLaunch = NO;
gFinderLaunch = NO;
}
gArgv = (char**) malloc (sizeof(*gArgv) * (gArgc+1));
assert (gArgv != NULL);
for (i = 0; i < gArgc; i++)
gArgv[i] = argv[i];
gArgv[i] = NULL;
gArgv = argv;

#if SDL_USE_NIB_FILE
[SDLApplication poseAsClass:[NSApplication class]];
Expand Down

0 comments on commit c303287

Please sign in to comment.