aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common.c2
-rw-r--r--src/internal.c35
-rw-r--r--src/mac.m10
-rw-r--r--src/types.h10
-rw-r--r--src/x11.c8
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);
}
diff --git a/src/mac.m b/src/mac.m
index 5236d43..b8e30df 100644
--- a/src/mac.m
+++ b/src/mac.m
@@ -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
diff --git a/src/x11.c b/src/x11.c
index 1dc4f9d..c3bf31f 100644
--- a/src/x11.c
+++ b/src/x11.c
@@ -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;