diff options
-rw-r--r-- | src/common.c | 2 | ||||
-rw-r--r-- | src/internal.c | 35 | ||||
-rw-r--r-- | src/mac.m | 10 | ||||
-rw-r--r-- | src/types.h | 10 | ||||
-rw-r--r-- | src/x11.c | 8 |
5 files changed, 46 insertions, 19 deletions
diff --git a/src/common.c b/src/common.c index c3f0818..3c2929f 100644 --- a/src/common.c +++ b/src/common.c @@ -255,7 +255,7 @@ puglGetTransientParent(const PuglView* const view) bool puglGetVisible(const PuglView* view) { - return view->visible; + return view->stage == PUGL_VIEW_STAGE_MAPPED; } void* diff --git a/src/internal.c b/src/internal.c index 2f277bb..ef1bcef 100644 --- a/src/internal.c +++ b/src/internal.c @@ -182,39 +182,60 @@ puglDispatchEvent(PuglView* view, const PuglEvent* event) switch (event->type) { case PUGL_NOTHING: break; + case PUGL_CREATE: + assert(view->stage == PUGL_VIEW_STAGE_ALLOCATED); + if (!(st0 = view->backend->enter(view, NULL))) { + st0 = view->eventFunc(view, event); + st1 = view->backend->leave(view, NULL); + } + view->stage = PUGL_VIEW_STAGE_CREATED; + break; + case PUGL_DESTROY: + assert(view->stage >= PUGL_VIEW_STAGE_CREATED); if (!(st0 = view->backend->enter(view, NULL))) { st0 = view->eventFunc(view, event); st1 = view->backend->leave(view, NULL); } + view->stage = PUGL_VIEW_STAGE_ALLOCATED; break; + case PUGL_CONFIGURE: + assert(view->stage >= PUGL_VIEW_STAGE_CREATED); if (puglMustConfigure(view, &event->configure)) { if (!(st0 = view->backend->enter(view, NULL))) { st0 = puglConfigure(view, event); st1 = view->backend->leave(view, NULL); } } + if (view->stage == PUGL_VIEW_STAGE_CREATED) { + view->stage = PUGL_VIEW_STAGE_CONFIGURED; + } break; + case PUGL_MAP: - if (!view->visible) { - view->visible = true; - st0 = view->eventFunc(view, event); + assert(view->stage >= PUGL_VIEW_STAGE_CONFIGURED); + if (view->stage != PUGL_VIEW_STAGE_MAPPED) { + st0 = view->eventFunc(view, event); + view->stage = PUGL_VIEW_STAGE_MAPPED; } break; + case PUGL_UNMAP: - if (view->visible) { - view->visible = false; - st0 = view->eventFunc(view, event); - } + assert(view->stage == PUGL_VIEW_STAGE_MAPPED); + st0 = view->eventFunc(view, event); + view->stage = PUGL_VIEW_STAGE_CONFIGURED; break; + case PUGL_EXPOSE: + assert(view->stage == PUGL_VIEW_STAGE_MAPPED); if (!(st0 = view->backend->enter(view, &event->expose))) { st0 = puglExpose(view, event); st1 = view->backend->leave(view, &event->expose); } break; + default: st0 = view->eventFunc(view, event); } @@ -213,7 +213,9 @@ updateViewRect(PuglView* view) - (void)setIsVisible:(BOOL)flag { - if (flag && !puglview->visible) { + [super setIsVisible:flag]; + + if (flag && puglview->stage < PUGL_VIEW_STAGE_MAPPED) { const PuglConfigureEvent ev = { PUGL_CONFIGURE, 0, @@ -227,13 +229,9 @@ updateViewRect(PuglView* view) configureEvent.configure = ev; puglDispatchEvent(puglview, &configureEvent); puglDispatchSimpleEvent(puglview, PUGL_MAP); - } else if (!flag && puglview->visible) { + } else if (!flag && puglview->stage == PUGL_VIEW_STAGE_MAPPED) { puglDispatchSimpleEvent(puglview, PUGL_UNMAP); } - - puglview->visible = flag; - - [super setIsVisible:flag]; } @end diff --git a/src/types.h b/src/types.h index dc2e29f..28d8548 100644 --- a/src/types.h +++ b/src/types.h @@ -33,6 +33,14 @@ typedef struct { size_t len; ///< Length of data in bytes } PuglBlob; +/// Stage of a view along its lifespan +typedef enum { + PUGL_VIEW_STAGE_ALLOCATED, + PUGL_VIEW_STAGE_CREATED, + PUGL_VIEW_STAGE_CONFIGURED, + PUGL_VIEW_STAGE_MAPPED, +} PuglViewStage; + /// Cross-platform view definition struct PuglViewImpl { PuglWorld* world; @@ -47,7 +55,7 @@ struct PuglViewImpl { PuglConfigureEvent lastConfigure; PuglHints hints; PuglViewSize sizeHints[PUGL_NUM_SIZE_HINTS]; - bool visible; + PuglViewStage stage; }; /// Cross-platform world definition @@ -825,9 +825,9 @@ translatePropertyNotify(PuglView* const view, XPropertyEvent message) } } - if (hidden && view->visible) { + if (hidden && view->stage == PUGL_VIEW_STAGE_MAPPED) { event.type = PUGL_UNMAP; - } else if (!hidden && !view->visible) { + } else if (!hidden && view->stage == PUGL_VIEW_STAGE_CONFIGURED) { event.type = PUGL_MAP; } @@ -1353,7 +1353,7 @@ flushExposures(PuglWorld* const world) PuglView* const view = world->views[i]; // Send update event so the application can trigger redraws - if (view->visible) { + if (view->stage == PUGL_VIEW_STAGE_MAPPED) { puglDispatchSimpleEvent(view, PUGL_UPDATE); } @@ -1568,7 +1568,7 @@ puglPostRedisplayRect(PuglView* const view, const PuglRect rect) if (view->world->impl->dispatchingEvents) { // Currently dispatching events, add/expand expose for the loop end mergeExposeEvents(&view->impl->pendingExpose.expose, &event); - } else if (view->visible) { + } else if (view->stage == PUGL_VIEW_STAGE_MAPPED) { // Not dispatching events, send an X expose so we wake up next time PuglEvent exposeEvent = {{PUGL_EXPOSE, 0}}; exposeEvent.expose = event; |