From 02d2704a0be7443907f5752c00b71feb58cc11dd Mon Sep 17 00:00:00 2001 From: David Robillard Date: Thu, 1 Sep 2016 22:26:22 -0400 Subject: Add PUGL_CLOSE event This allows purely event-driven applications to handle window close. Something more extensible for WM message seems like it might be a good idea here, but I can't think of specific uses, so this will do. --- pugl/event.h | 10 ++++++++++ pugl/pugl_internal.h | 6 ++++++ pugl/pugl_osx.m | 9 +++++++-- pugl/pugl_win.cpp | 5 +---- pugl/pugl_x11.c | 20 +++++++++----------- 5 files changed, 33 insertions(+), 17 deletions(-) diff --git a/pugl/event.h b/pugl/event.h index 2c48369..8ed1b2e 100644 --- a/pugl/event.h +++ b/pugl/event.h @@ -38,6 +38,7 @@ typedef enum { PUGL_BUTTON_RELEASE, PUGL_CONFIGURE, PUGL_EXPOSE, + PUGL_CLOSE, PUGL_KEY_PRESS, PUGL_KEY_RELEASE, PUGL_ENTER_NOTIFY, @@ -116,6 +117,15 @@ typedef struct { int count; /**< Number of expose events to follow. */ } PuglEventExpose; +/** + Window close event. +*/ +typedef struct { + PuglEventType type; /**< PUGL_CLOSE. */ + PuglView* view; /**< View that received this event. */ + uint32_t flags; /**< Bitwise OR of PuglEventFlag values. */ +} PuglEventClose; + /** Key press/release event. diff --git a/pugl/pugl_internal.h b/pugl/pugl_internal.h index 23abebf..d4ba126 100644 --- a/pugl/pugl_internal.h +++ b/pugl/pugl_internal.h @@ -324,6 +324,12 @@ puglDispatchEvent(PuglView* view, const PuglEvent* event) puglLeaveContext(view, true); } break; + case PUGL_CLOSE: + if (view->closeFunc) { + view->closeFunc(view); + } + view->redisplay = false; + break; case PUGL_MOTION_NOTIFY: view->event_timestamp_ms = event->motion.time; view->mods = event->motion.state; diff --git a/pugl/pugl_osx.m b/pugl/pugl_osx.m index ecf9373..72e4da9 100644 --- a/pugl/pugl_osx.m +++ b/pugl/pugl_osx.m @@ -82,8 +82,13 @@ struct PuglInternalsImpl { - (BOOL)windowShouldClose:(id)sender { - if (puglview->closeFunc) - puglview->closeFunc(puglview); + const PuglEventClose ev = { + PUGL_CLOSE, + puglview, + 0 + }; + puglDispatchEvent(puglview, (PuglEvent*)&ev); + return YES; } diff --git a/pugl/pugl_win.cpp b/pugl/pugl_win.cpp index c061f25..eb87197 100644 --- a/pugl/pugl_win.cpp +++ b/pugl/pugl_win.cpp @@ -574,10 +574,7 @@ handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam) break; case WM_QUIT: case PUGL_LOCAL_CLOSE_MSG: - if (view->closeFunc) { - view->closeFunc(view); - view->redisplay = false; - } + event.close.type = PUGL_CLOSE; break; default: return DefWindowProc( diff --git a/pugl/pugl_x11.c b/pugl/pugl_x11.c index 4d7010b..f91aa24 100644 --- a/pugl/pugl_x11.c +++ b/pugl/pugl_x11.c @@ -461,6 +461,14 @@ translateEvent(PuglView* view, XEvent xevent) } switch (xevent.type) { + case ClientMessage: { + char* type = XGetAtomName(view->impl->display, + xevent.xclient.message_type); + if (!strcmp(type, "WM_PROTOCOLS")) { + event.type = PUGL_CLOSE; + } + break; + } case ConfigureNotify: event.type = PUGL_CONFIGURE; event.configure.x = xevent.xconfigure.x; @@ -605,17 +613,7 @@ puglProcessEvents(PuglView* view) XEvent xevent; while (XPending(view->impl->display) > 0) { XNextEvent(view->impl->display, &xevent); - if (xevent.type == ClientMessage) { - // Handle close message - char* type = XGetAtomName(view->impl->display, - xevent.xclient.message_type); - if (!strcmp(type, "WM_PROTOCOLS") && view->closeFunc) { - view->closeFunc(view); - view->redisplay = false; - } - XFree(type); - continue; - } else if (xevent.type == KeyRelease) { + if (xevent.type == KeyRelease) { // Ignore key repeat if necessary if (view->ignoreKeyRepeat && XEventsQueued(view->impl->display, QueuedAfterReading)) { -- cgit v1.2.1