Added uiMain() and friends on macOS and refined the tests. So now we'll need to add a timeout mechanism because that sendEvent: stuff really is still neeeded and I'd like to prevent shenanigans later.
This commit is contained in:
parent
2c57498e44
commit
9c70782a0f
|
@ -7,7 +7,34 @@
|
|||
@implementation uiprivApplication
|
||||
@end
|
||||
|
||||
static NSApplication *uiprivApp;
|
||||
@interface uiprivApplicationDelegate : NSObject<NSApplicationDelegate>
|
||||
@end
|
||||
|
||||
static uiprivApplication *uiprivApp;
|
||||
static uiprivApplicationDelegate *uiprivAppDelegate;
|
||||
|
||||
@implementation uiprivApplicationDelegate
|
||||
|
||||
#if 0
|
||||
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)app
|
||||
{
|
||||
// for debugging
|
||||
NSLog(@"in applicationShouldTerminate:");
|
||||
if (uiprivShouldQuit()) {
|
||||
canQuit = YES;
|
||||
// this will call terminate:, which is the same as uiQuit()
|
||||
return NSTerminateNow;
|
||||
}
|
||||
return NSTerminateCancel;
|
||||
}
|
||||
#endif
|
||||
|
||||
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)app
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#define errNSAppAlreadyInitialized "NSApp is not of type uiprivApplication; was likely already initialized beforehand"
|
||||
|
||||
|
@ -25,6 +52,31 @@ int uiInit(void *options, uiInitError *err)
|
|||
if (![NSApp isKindOfClass:[uiprivApplication class]])
|
||||
return uiprivInitReturnError(err, errNSAppAlreadyInitialized);
|
||||
|
||||
// don't check for a NO return; something (launch services?) causes running from application bundles to always return NO when asking to change activation policy, even if the change is to the same activation policy!
|
||||
// see https://github.com/andlabs/ui/issues/6
|
||||
[uiprivApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||
|
||||
uiprivAppDelegate = [uiprivApplicationDelegate new];
|
||||
[uiprivApp setDelegate:uiprivAppDelegate];
|
||||
|
||||
uiprivMarkInitialized();
|
||||
return 1;
|
||||
}
|
||||
|
||||
void uiMain(void)
|
||||
{
|
||||
[uiprivApp run];
|
||||
}
|
||||
|
||||
void uiQuit(void)
|
||||
{
|
||||
[uiprivApp stop:uiprivApp];
|
||||
}
|
||||
|
||||
// thanks to mikeash in irc.freenode.net/#macdev for suggesting the use of Grand Central Dispatch for this
|
||||
void uiQueueMain(void (*f)(void *data), void *data)
|
||||
{
|
||||
// dispatch_get_main_queue() is a serial queue so it will not execute multiple uiQueueMain() functions concurrently
|
||||
// the signature of f matches dispatch_function_t
|
||||
dispatch_async_f(dispatch_get_main_queue(), data, f);
|
||||
}
|
||||
|
|
|
@ -52,8 +52,28 @@ static void queued(void *data)
|
|||
int *flag = (int *) data;
|
||||
|
||||
*flag = 1;
|
||||
uiQuit();
|
||||
}
|
||||
|
||||
testingTest(QueueMain)
|
||||
{
|
||||
int flag = 0;
|
||||
|
||||
uiQueueMain(queued, &flag);
|
||||
uiMain();
|
||||
if (flag != 1)
|
||||
testingTErrorf(t, "uiQueueMain didn't set flag properly: got %d, want 1", flag);
|
||||
}
|
||||
|
||||
testingTest(QueueMain_Sequence)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// TODO testingTest(QueueMain_DifferentThread)
|
||||
// TODO testingTest(QueueMain_DifferentThreadSequence)
|
||||
|
||||
#if 0
|
||||
static void timer(void *data)
|
||||
{
|
||||
int *n = (int *) data;
|
||||
|
@ -62,12 +82,7 @@ static void timer(void *data)
|
|||
*n++;
|
||||
}
|
||||
|
||||
testingTest(QueueMain)
|
||||
{
|
||||
}
|
||||
|
||||
// TODO testingTest(QueueMain_DifferentThread)
|
||||
|
||||
testingTest(Timer)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -87,23 +87,6 @@ static BOOL stepsIsRunning;
|
|||
[super dealloc];
|
||||
}
|
||||
|
||||
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)app
|
||||
{
|
||||
// for debugging
|
||||
NSLog(@"in applicationShouldTerminate:");
|
||||
if (uiprivShouldQuit()) {
|
||||
canQuit = YES;
|
||||
// this will call terminate:, which is the same as uiQuit()
|
||||
return NSTerminateNow;
|
||||
}
|
||||
return NSTerminateCancel;
|
||||
}
|
||||
|
||||
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)app
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
uiInitOptions uiprivOptions;
|
||||
|
@ -112,12 +95,6 @@ const char *uiInit(uiInitOptions *o)
|
|||
{
|
||||
@autoreleasepool {
|
||||
uiprivOptions = *o;
|
||||
app = [[uiprivApplicationClass sharedApplication] retain];
|
||||
// don't check for a NO return; something (launch services?) causes running from application bundles to always return NO when asking to change activation policy, even if the change is to the same activation policy!
|
||||
// see https://github.com/andlabs/ui/issues/6
|
||||
[uiprivNSApp() setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||
delegate = [uiprivAppDelegate new];
|
||||
[uiprivNSApp() setDelegate:delegate];
|
||||
|
||||
uiprivInitAlloc();
|
||||
uiprivLoadFutures();
|
||||
|
@ -228,21 +205,6 @@ int uiprivMainStep(uiprivNextEventArgs *nea, BOOL (^interceptEvent)(NSEvent *e))
|
|||
}
|
||||
}
|
||||
|
||||
void uiQuit(void)
|
||||
{
|
||||
canQuit = YES;
|
||||
[uiprivNSApp() terminate:uiprivNSApp()];
|
||||
}
|
||||
|
||||
// thanks to mikeash in irc.freenode.net/#macdev for suggesting the use of Grand Central Dispatch for this
|
||||
// LONGTERM will dispatch_get_main_queue() break after _CFRunLoopSetCurrent()?
|
||||
void uiQueueMain(void (*f)(void *data), void *data)
|
||||
{
|
||||
// dispatch_get_main_queue() is a serial queue so it will not execute multiple uiQueueMain() functions concurrently
|
||||
// the signature of f matches dispatch_function_t
|
||||
dispatch_async_f(dispatch_get_main_queue(), data, f);
|
||||
}
|
||||
|
||||
@interface uiprivTimerDelegate : NSObject {
|
||||
int (*f)(void *data);
|
||||
void *data;
|
||||
|
|
Loading…
Reference in New Issue