Finished cleaning up the GTK+ lifetiming code. Yeah, this will definitely work.
This commit is contained in:
parent
48c609b5c3
commit
89d584cdcd
2
TODO.md
2
TODO.md
|
@ -20,7 +20,7 @@
|
||||||
- verify that uiParentSetMainControl() does indeed not update
|
- verify that uiParentSetMainControl() does indeed not update
|
||||||
- settle differences between intmax_t and uintmax_t
|
- settle differences between intmax_t and uintmax_t
|
||||||
- settle onDestroy/destroy naming
|
- settle onDestroy/destroy naming
|
||||||
- clean up Unix lifetiming code
|
- clean up Windows lifetiming code
|
||||||
|
|
||||||
ultimately:
|
ultimately:
|
||||||
- make everything vtable-based
|
- make everything vtable-based
|
||||||
|
|
|
@ -25,8 +25,10 @@ static void singleDestroy(uiControl *c)
|
||||||
(*(s->onDestroy))(s->onDestroyData);
|
(*(s->onDestroy))(s->onDestroyData);
|
||||||
// then mark that we are ready to be destroyed
|
// then mark that we are ready to be destroyed
|
||||||
g_signal_handler_disconnect(s->immediate, s->destroyBlocker);
|
g_signal_handler_disconnect(s->immediate, s->destroyBlocker);
|
||||||
// then actually destroy
|
// then actually destroy (TODO sync these comments)
|
||||||
gtk_widget_destroy(s->immediate);
|
gtk_widget_destroy(s->immediate);
|
||||||
|
// and free ourselves
|
||||||
|
uiFree(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uintptr_t singleHandle(uiControl *c)
|
static uintptr_t singleHandle(uiControl *c)
|
||||||
|
|
|
@ -46,6 +46,8 @@ static void uipParent_dispose(GObject *obj)
|
||||||
if (!p->canDestroy)
|
if (!p->canDestroy)
|
||||||
complain("attempt to dispose uiParent with uipParent at %p before uiParentDestroy()", p);
|
complain("attempt to dispose uiParent with uipParent at %p before uiParentDestroy()", p);
|
||||||
if (p->children != NULL) {
|
if (p->children != NULL) {
|
||||||
|
if (p->children->len != 0)
|
||||||
|
complain("disposing uiParent with uipParent at %p while there are still children", p);
|
||||||
g_ptr_array_unref(p->children);
|
g_ptr_array_unref(p->children);
|
||||||
p->children = NULL;
|
p->children = NULL;
|
||||||
}
|
}
|
||||||
|
@ -150,6 +152,8 @@ static void parentDestroy(uiParent *pp)
|
||||||
p->canDestroy = TRUE;
|
p->canDestroy = TRUE;
|
||||||
// finally, destroy the parent
|
// finally, destroy the parent
|
||||||
gtk_widget_destroy(GTK_WIDGET(p));
|
gtk_widget_destroy(GTK_WIDGET(p));
|
||||||
|
// and free ourselves
|
||||||
|
uiFree(pp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uintptr_t parentHandle(uiParent *p)
|
static uintptr_t parentHandle(uiParent *p)
|
||||||
|
|
|
@ -10,7 +10,7 @@ struct window {
|
||||||
int (*onClosing)(uiWindow *, void *);
|
int (*onClosing)(uiWindow *, void *);
|
||||||
void *onClosingData;
|
void *onClosingData;
|
||||||
int margined;
|
int margined;
|
||||||
gboolean canDestroy;
|
gulong destroyBlocker;
|
||||||
};
|
};
|
||||||
|
|
||||||
static gboolean onClosing(GtkWidget *win, GdkEvent *e, gpointer data)
|
static gboolean onClosing(GtkWidget *win, GdkEvent *e, gpointer data)
|
||||||
|
@ -28,13 +28,9 @@ static int defaultOnClosing(uiWindow *w, void *data)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void onDestroy(GtkWidget *widget, gpointer data)
|
static void destroyBlocker(GtkWidget *widget, gpointer data)
|
||||||
{
|
{
|
||||||
struct window *w = (struct window *) data;
|
complain("attempt to dispose uiWindow at %p before uiWindowDestroy()", data);
|
||||||
|
|
||||||
if (!w->canDestroy)
|
|
||||||
complain("attempt to dispose uiWindow at %p before uiWindowDestroy()", w);
|
|
||||||
uiFree(w);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO should we change the GtkWindow's child first?
|
// TODO should we change the GtkWindow's child first?
|
||||||
|
@ -47,9 +43,11 @@ static void windowDestroy(uiWindow *ww)
|
||||||
// next, destroy the content uiParent
|
// next, destroy the content uiParent
|
||||||
uiParentDestroy(w->content);
|
uiParentDestroy(w->content);
|
||||||
// now that we cleaned up properly, we can mark our window as ready to be destroyed
|
// now that we cleaned up properly, we can mark our window as ready to be destroyed
|
||||||
w->canDestroy = TRUE;
|
g_signal_handler_disconnect(w->widget, w->destroyBlocker);
|
||||||
// finally, destroy the window
|
// finally, destroy the window
|
||||||
gtk_widget_destroy(w->widget);
|
gtk_widget_destroy(w->widget);
|
||||||
|
// and free ourselves
|
||||||
|
uiFree(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uintptr_t windowHandle(uiWindow *ww)
|
static uintptr_t windowHandle(uiWindow *ww)
|
||||||
|
@ -136,7 +134,7 @@ uiWindow *uiNewWindow(const char *title, int width, int height)
|
||||||
gtk_window_resize(w->window, width, height);
|
gtk_window_resize(w->window, width, height);
|
||||||
|
|
||||||
g_signal_connect(w->widget, "delete-event", G_CALLBACK(onClosing), w);
|
g_signal_connect(w->widget, "delete-event", G_CALLBACK(onClosing), w);
|
||||||
g_signal_connect(w->widget, "destroy", G_CALLBACK(onDestroy), w);
|
w->destroyBlocker = g_signal_connect(w->widget, "destroy", G_CALLBACK(destroyBlocker), w);
|
||||||
|
|
||||||
w->content = uiNewParent((uintptr_t) (w->container));
|
w->content = uiNewParent((uintptr_t) (w->container));
|
||||||
w->onClosing = defaultOnClosing;
|
w->onClosing = defaultOnClosing;
|
||||||
|
|
Loading…
Reference in New Issue