From 9be7bab7cf3c63cafa07e5a70d6c59559ffdc1de Mon Sep 17 00:00:00 2001 From: David Robillard Date: Mon, 9 Mar 2020 21:49:58 +0100 Subject: Add PuglEventClient and puglSendEvent() This event makes it possible to send an arbitrary event to a view, which is useful for many things. In particular, this method of communication with views will wake up the event loop, unlike hacks in applications that share data in some other way. --- pugl/detail/mac.m | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'pugl/detail/mac.m') diff --git a/pugl/detail/mac.m b/pugl/detail/mac.m index c083919..837d3cc 100644 --- a/pugl/detail/mac.m +++ b/pugl/detail/mac.m @@ -947,6 +947,32 @@ puglPollEvents(PuglWorld* world, const double timeout) return PUGL_SUCCESS; } +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:event->client.data1 + data2:event->client.data2]; + + [view->world->impl->app postEvent:nsevent atStart:false]; + return PUGL_SUCCESS; + } + + return PUGL_UNSUPPORTED_TYPE; +} + #ifndef PUGL_DISABLE_DEPRECATED PuglStatus puglWaitForEvent(PuglView* view) @@ -955,6 +981,25 @@ 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 PuglEventClient event = {PUGL_CLIENT, + 0, + [ev data1], + [ev data2]}; + + view->eventFunc(view, (const PuglEvent*)&event); + } + } +} + PUGL_API PuglStatus puglDispatchEvents(PuglWorld* world) { @@ -970,6 +1015,9 @@ puglDispatchEvents(PuglWorld* world) // Event is later, put it back for the next iteration and return [world->impl->app postEvent:ev atStart:true]; break; + } else if ([ev type] == NSApplicationDefined && + [ev subtype] == PUGL_CLIENT) { + dispatchClientEvent(world, ev); } [world->impl->app sendEvent: ev]; -- cgit v1.2.1