Commit b88a981c authored by Sam Lantinga's avatar Sam Lantinga

Date: Thu, 2 Sep 2004 19:35:51 +0200

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).

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%40958
parent 48329dae
...@@ -33,16 +33,27 @@ static int gArgc; ...@@ -33,16 +33,27 @@ static int gArgc;
static char **gArgv; static char **gArgv;
static BOOL gFinderLaunch; 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 #if SDL_USE_NIB_FILE
/* A helper category for NSString */ /* A helper category for NSString */
@interface NSString (ReplaceSubString) @interface NSString (ReplaceSubString)
- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString; - (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString;
@end @end
#else
/* An internal Apple class used to setup Apple menus */
@interface NSAppleMenuController:NSObject {}
- (void)controlMenu:(NSMenu *)aMenu;
@end
#endif #endif
@interface SDLApplication : NSApplication @interface SDLApplication : NSApplication
...@@ -59,33 +70,24 @@ static BOOL gFinderLaunch; ...@@ -59,33 +70,24 @@ static BOOL gFinderLaunch;
} }
@end @end
/* The main class of the application, the application's delegate */ /* The main class of the application, the application's delegate */
@implementation SDLMain @implementation SDLMain
/* Set the working directory to the .app's parent directory */ /* Set the working directory to the .app's parent directory */
- (void) setupWorkingDirectory:(BOOL)shouldChdir - (void) setupWorkingDirectory:(BOOL)shouldChdir
{ {
if (shouldChdir) if (shouldChdir)
{ {
char parentdir[MAXPATHLEN]; char parentdir[MAXPATHLEN];
char *c; CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle());
CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url);
strncpy ( parentdir, gArgv[0], sizeof(parentdir) ); if (CFURLGetFileSystemRepresentation(url2, true, parentdir, MAXPATHLEN)) {
c = (char*) parentdir;
while (*c != '\0') /* go to end */
c++;
while (*c != '/') /* back up to parent */
c--;
*c++ = '\0'; /* cut off last part (binary name) */
assert ( chdir (parentdir) == 0 ); /* chdir to the binary app's parent */ assert ( chdir (parentdir) == 0 ); /* chdir to the binary app's parent */
assert ( chdir ("../../../") == 0 ); /* chdir to the .app's parent */
} }
CFRelease(url);
CFRelease(url2);
}
} }
#if SDL_USE_NIB_FILE #if SDL_USE_NIB_FILE
...@@ -115,39 +117,57 @@ static BOOL gFinderLaunch; ...@@ -115,39 +117,57 @@ static BOOL gFinderLaunch;
#else #else
void setupAppleMenu(void) static void setApplicationMenu(void)
{ {
/* warning: this code is very odd */ /* warning: this code is very odd */
NSAppleMenuController *appleMenuController;
NSMenu *appleMenu; NSMenu *appleMenu;
NSMenuItem *appleMenuItem; NSMenuItem *menuItem;
NSString *title;
NSString *appName;
appleMenuController = [[NSAppleMenuController alloc] init]; appName = getApplicationName();
appleMenu = [[NSMenu alloc] initWithTitle:@""]; appleMenu = [[NSMenu alloc] initWithTitle:@""];
appleMenuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
/* Add menu items */
[appleMenuItem setSubmenu:appleMenu]; title = [@"About " stringByAppendingString:appName];
[appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
/* yes, we do need to add it and then remove it --
if you don't add it, it doesn't get displayed [appleMenu addItem:[NSMenuItem separatorItem]];
if you don't remove it, you have an extra, titleless item in the menubar
when you remove it, it appears to stick around title = [@"Hide " stringByAppendingString:appName];
very, very odd */ [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"];
[[NSApp mainMenu] addItem:appleMenuItem];
[appleMenuController controlMenu:appleMenu]; menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
[[NSApp mainMenu] removeItem:appleMenuItem]; [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]; [appleMenu release];
[appleMenuItem release]; [menuItem release];
} }
/* Create a window menu */ /* Create a window menu */
void setupWindowMenu(void) static void setupWindowMenu(void)
{ {
NSMenu *windowMenu; NSMenu *windowMenu;
NSMenuItem *windowMenuItem; NSMenuItem *windowMenuItem;
NSMenuItem *menuItem; NSMenuItem *menuItem;
windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
/* "Minimize" item */ /* "Minimize" item */
...@@ -169,7 +189,7 @@ void setupWindowMenu(void) ...@@ -169,7 +189,7 @@ void setupWindowMenu(void)
} }
/* Replacement for NSApplicationMain */ /* Replacement for NSApplicationMain */
void CustomApplicationMain (argc, argv) static void CustomApplicationMain (argc, argv)
{ {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
SDLMain *sdlMain; SDLMain *sdlMain;
...@@ -190,7 +210,7 @@ void CustomApplicationMain (argc, argv) ...@@ -190,7 +210,7 @@ void CustomApplicationMain (argc, argv)
/* Set up the menubar */ /* Set up the menubar */
[NSApp setMainMenu:[[NSMenu alloc] init]]; [NSApp setMainMenu:[[NSMenu alloc] init]];
setupAppleMenu(); setApplicationMenu();
setupWindowMenu(); setupWindowMenu();
/* Create SDLMain and make it the app delegate */ /* Create SDLMain and make it the app delegate */
...@@ -216,7 +236,7 @@ void CustomApplicationMain (argc, argv) ...@@ -216,7 +236,7 @@ void CustomApplicationMain (argc, argv)
#if SDL_USE_NIB_FILE #if SDL_USE_NIB_FILE
/* Set the main menu to contain the real app name instead of "SDL App" */ /* 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 #endif
/* Hand off to main application code */ /* Hand off to main application code */
...@@ -289,11 +309,7 @@ int main (int argc, char **argv) ...@@ -289,11 +309,7 @@ int main (int argc, char **argv)
gArgc = argc; gArgc = argc;
gFinderLaunch = NO; gFinderLaunch = NO;
} }
gArgv = (char**) malloc (sizeof(*gArgv) * (gArgc+1)); gArgv = argv;
assert (gArgv != NULL);
for (i = 0; i < gArgc; i++)
gArgv[i] = argv[i];
gArgv[i] = NULL;
#if SDL_USE_NIB_FILE #if SDL_USE_NIB_FILE
[SDLApplication poseAsClass:[NSApplication class]]; [SDLApplication poseAsClass:[NSApplication class]];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment