diff options
author | reuk <reuk@users.noreply.github.com> | 2021-07-30 14:14:47 +0100 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2023-01-11 18:54:27 -0500 |
commit | 28d75f7e20d49b5fe6b1d00a6088c84fc7c1f9ce (patch) | |
tree | fc38d5c904601834af2156ddb6df42cfeb34c744 | |
parent | 3acb303c68f702dce43631caad206c4b4e3ed563 (diff) | |
download | pugl-28d75f7e20d49b5fe6b1d00a6088c84fc7c1f9ce.tar.gz pugl-28d75f7e20d49b5fe6b1d00a6088c84fc7c1f9ce.tar.bz2 pugl-28d75f7e20d49b5fe6b1d00a6088c84fc7c1f9ce.zip |
MacOS: Avoid calling sendEvent in modules
-rw-r--r-- | src/common.c | 1 | ||||
-rw-r--r-- | src/mac.m | 87 | ||||
-rw-r--r-- | src/types.h | 1 |
3 files changed, 33 insertions, 56 deletions
diff --git a/src/common.c b/src/common.c index 20e844a..7113461 100644 --- a/src/common.c +++ b/src/common.c @@ -50,6 +50,7 @@ puglNewWorld(PuglWorldType type, PuglWorldFlags flags) } world->startTime = puglGetTime(world); + world->type = type; puglSetString(&world->className, "Pugl"); @@ -1545,23 +1545,21 @@ PuglStatus puglSendEvent(PuglView* view, const PuglEvent* event) { if (event->type == PUGL_CLIENT) { - PuglWrapperView* wrapper = view->impl->wrapperView; - const NSWindow* window = [wrapper window]; - const NSRect rect = [wrapper frame]; - const NSPoint center = {NSMidX(rect), NSMidY(rect)}; - - NSEvent* nsevent = - [NSEvent otherEventWithType:NSApplicationDefined - location:center - modifierFlags:0 - timestamp:[[NSProcessInfo processInfo] systemUptime] - windowNumber:window.windowNumber - context:nil - subtype:PUGL_CLIENT - data1:(NSInteger)event->client.data1 - data2:(NSInteger)event->client.data2]; - - [view->world->impl->app postEvent:nsevent atStart:false]; + PuglEvent copiedEvent = *event; + + CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler( + NULL, + kCFRunLoopBeforeSources, + false, + 0, + ^(CFRunLoopObserverRef ref, CFRunLoopActivity activity) { + (void)ref; + (void)activity; + puglDispatchEvent(view, &copiedEvent); + }); + + CFRunLoopAddObserver(CFRunLoopGetMain(), observer, kCFRunLoopCommonModes); + CFRelease(observer); return PUGL_SUCCESS; } @@ -1581,49 +1579,26 @@ puglWaitForEvent(PuglView* view) } #endif -static void -dispatchClientEvent(PuglWorld* world, NSEvent* ev) -{ - NSWindow* win = [ev window]; - NSPoint loc = [ev locationInWindow]; - for (size_t i = 0; i < world->numViews; ++i) { - PuglView* view = world->views[i]; - PuglWrapperView* wrapper = view->impl->wrapperView; - if ([wrapper window] == win && NSPointInRect(loc, [wrapper frame])) { - const PuglClientEvent event = { - PUGL_CLIENT, 0, (uintptr_t)[ev data1], (uintptr_t)[ev data2]}; - - PuglEvent clientEvent; - clientEvent.client = event; - puglDispatchEvent(view, &clientEvent); - } - } -} - PuglStatus puglUpdate(PuglWorld* world, const double timeout) { @autoreleasepool { - NSDate* date = - ((timeout < 0) ? [NSDate distantFuture] - : [NSDate dateWithTimeIntervalSinceNow:timeout]); - - for (NSEvent* ev = NULL; - (ev = [world->impl->app nextEventMatchingMask:NSAnyEventMask - untilDate:date - inMode:NSDefaultRunLoopMode - dequeue:YES]);) { - if ([ev type] == NSApplicationDefined && - [ev subtype] == (NSEventSubtype)PUGL_CLIENT) { - dispatchClientEvent(world, ev); - } - - [world->impl->app sendEvent:ev]; - - if (timeout < 0) { - // Now that we've waited and got an event, set the date to now to avoid - // looping forever - date = [NSDate date]; + if (world->type == PUGL_PROGRAM) { + NSDate* date = + ((timeout < 0) ? [NSDate distantFuture] + : [NSDate dateWithTimeIntervalSinceNow:timeout]); + + for (NSEvent* ev = NULL; + (ev = [world->impl->app nextEventMatchingMask:NSAnyEventMask + untilDate:date + inMode:NSDefaultRunLoopMode + dequeue:YES]);) { + [world->impl->app sendEvent:ev]; + + if (timeout < 0) { + // Now that we've got an event, mark the date to avoid looping forever + date = [NSDate date]; + } } } diff --git a/src/types.h b/src/types.h index 35f29c5..12e4acf 100644 --- a/src/types.h +++ b/src/types.h @@ -73,6 +73,7 @@ struct PuglWorldImpl { double startTime; size_t numViews; PuglView** views; + PuglWorldType type; }; /// Opaque surface used by graphics backend |