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
|
@implementation uiprivApplication
|
||||||
@end
|
@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"
|
#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]])
|
if (![NSApp isKindOfClass:[uiprivApplication class]])
|
||||||
return uiprivInitReturnError(err, errNSAppAlreadyInitialized);
|
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();
|
uiprivMarkInitialized();
|
||||||
return 1;
|
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;
|
int *flag = (int *) data;
|
||||||
|
|
||||||
*flag = 1;
|
*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)
|
static void timer(void *data)
|
||||||
{
|
{
|
||||||
int *n = (int *) data;
|
int *n = (int *) data;
|
||||||
|
@ -62,12 +82,7 @@ static void timer(void *data)
|
||||||
*n++;
|
*n++;
|
||||||
}
|
}
|
||||||
|
|
||||||
testingTest(QueueMain)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO testingTest(QueueMain_DifferentThread)
|
|
||||||
|
|
||||||
testingTest(Timer)
|
testingTest(Timer)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -87,23 +87,6 @@ static BOOL stepsIsRunning;
|
||||||
[super dealloc];
|
[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
|
@end
|
||||||
|
|
||||||
uiInitOptions uiprivOptions;
|
uiInitOptions uiprivOptions;
|
||||||
|
@ -112,12 +95,6 @@ const char *uiInit(uiInitOptions *o)
|
||||||
{
|
{
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
uiprivOptions = *o;
|
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();
|
uiprivInitAlloc();
|
||||||
uiprivLoadFutures();
|
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 {
|
@interface uiprivTimerDelegate : NSObject {
|
||||||
int (*f)(void *data);
|
int (*f)(void *data);
|
||||||
void *data;
|
void *data;
|
||||||
|
|
Loading…
Reference in New Issue