On Windows and GTK+ it is possible to have a fully nested run loop that can still pump events to windows that are not waiting for modal input. However, with Cocoa, all I see for NSAlert are -[NSAlert runModal]
, which affects all windows, and -[NSAlert beginSheetForModal:...:]
, which are modal to the given window and are not code-modal. Code-modal in this case means the function does not return until the NSAlert is dismissed. (I'll also need to do this for the other various dialogs, such as NSOpenPanel.)
Basically what I would like to know is if it is possible to model a call to -[NSAlert beginSheetModalForWindow:modalDelegate:didEndSelector:contextInfo:]
that safely allows other window events to continue running, but that does not itself return until the dialog is dismissed. For instance, something like
[alert beginSheetModalForWindow:w modalDelegate:delegate didEndSelector:... contextInfo:NULL];
while (!delegate->done)
[NSApp doMainLoopIteration]; // not real
but not racy like that. Or perhaps even something like
[alert ...];
[delegate waitForAlertDidEnd];
This is being called from a C function for interop with a non-Objective-C environment.
Is this possible, or am I out of luck?
This needs to target Mac OS X 10.7+, so I can't use the new block-based NSAlert method which was introduced in 10.9.
Thanks!
Update
Now I have some actual code to show for this:
NSInteger ret;
[box beginSheetModalForWindow:parent
modalDelegate:[NSApp delegate]
didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:)
contextInfo:&ret];
// TODO
return (intptr_t) ret;
I'd like the TODO to be a wait for the didEndSelector
to run, while still pumping other events. The didEndSelector
is
- (void)alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)data
{
NSInteger *ret = (NSInteger *) data;
*ret = returnCode;
}
If there's a statement that I need to put in there to make what I want work, that can be done too.
Thanks!