Re: [Pyobjc-dev] Multiple Document App Template
Brought to you by:
ronaldoussoren
From: Bob I. <bo...@re...> - 2003-01-15 00:07:54
|
On Tuesday, Jan 14, 2003, at 16:07 America/New_York, Bill Bumgarner wrote: > Nothing so complex -- it is just a bug in NSApplicationMain(). > NSApplicationMain() ignores the array of arguments passed to it and > uses [[NSProcessInfo processInfo] arguments] instead. I didn't know you could set NSProcessInfo like that, I wish I had known that before.. I tried to do the equivalent once by doing some tricks with the end of the stack, but you can easily muck up environment variables and stuff that way if you don't do it just right. Knowing that it's possible this way, it should be relatively painless to engineer another nasty private thing -- a method for morphing a console app started with ANY command line into a Cocoa app, even if it's not in a bundle or has been running a while as a console app and Cocoa wasn't linked in at the time it started. Note that I haven't tried it since 10.1, but it worked then if you had started the app with full path, I imagine it still works now but I haven't tested it.. It also would've worked with any argv if I managed to figure out the nastiness of setting up argv/argc/environment/etc post-launch (I confirmed this experimentally by intentionally passing a large enough argv such that I could do the full-path thing).. From what it looks like, your NSProcessInfo hack *might* just do the trick. If someone gets it working well, it might be worthwhile to add it to pyobjc in some way.. i.e. from objc import evilcocoahack Obviously it's not of so much use for a released application since you likely have the convenience of doing the app bundle thing, but for development/experimentation it might be worthwhile. I actually had code similar to this run on import of a python module to make sure that you were a Cocoa app: // Linking to Cocoa is sufficient to bring these symbols in struct CPSProcessSerNum { UInt32 lo; UInt32 hi; }; typedef struct CPSProcessSerNum CPSProcessSerNum; extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn); extern OSErr CPSSetProcessName ( CPSProcessSerNum *psn, char *processname); // I don't know which of these arguments are real and which aren't.. doesn't so much matter since it's // passed by register. I figured these out with gdb so I don't know how many arguments there // actually are extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5); extern OSErr CPSGetFrontProcess( CPSProcessSerNum *psn); // Note that this doesn't do anything bad (in my experience) if you're already a gui app void evilMorphIntoCocoaApp(void) { CPSProcessSerNum PSN; // XXX set NSProcessInfo properly [NSApplication sharedApplication]; if (!CPSGetCurrentProcess(&PSN)) // IIRC this fails if you're already a GUI app, so no harm done if (!CPSSetProcessName(&PSN,"yourProcessName")) if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103)) if (!CPSSetFrontProcess(&PSN)) [NSApplication sharedApplication]; } |