Cleaned up memory leaks in the GTK+ backend.

This commit is contained in:
Pietro Gagliardi 2015-04-08 01:16:22 -04:00
parent f5c8bdd4b3
commit d37bc67158
4 changed files with 37 additions and 3 deletions

View File

@ -19,7 +19,13 @@ static void defaultOnClicked(uiControl *c, void *data)
// do nothing
}
// TODO destruction
static void onDestroy(GtkWidget *widget, gpointer data)
{
struct button *b = (struct button *) data;
uiFree(b);
}
uiControl *uiNewButton(const char *text)
{
struct button *b;
@ -33,6 +39,7 @@ uiControl *uiNewButton(const char *text)
NULL);
widget = GTK_WIDGET(uiControlHandle(b->c));
g_signal_connect(widget, "destroy", G_CALLBACK(onDestroy), b);
g_signal_connect(widget, "clicked", G_CALLBACK(onClicked), b);
b->onClicked = defaultOnClicked;

View File

@ -15,6 +15,10 @@ static void uiContainer_init(uiContainer *c)
static void uiContainer_dispose(GObject *obj)
{
g_ptr_array_unref(uiContainer(obj)->children);
if (uiContainer(obj)->child != NULL) {
uiControlDestroy(uiContainer(obj)->child);
uiContainer(obj)->child = NULL;
}
G_OBJECT_CLASS(uiContainer_parent_class)->dispose(obj);
}

View File

@ -13,6 +13,11 @@ struct uiSingleWidgetControl {
#define S(c) ((uiSingleWidgetControl *) (c))
static void singleDestroy(uiControl *c)
{
gtk_widget_destroy(S(c)->immediate);
}
static uintptr_t singleHandle(uiControl *c)
{
return (uintptr_t) (S(c)->widget);
@ -48,7 +53,12 @@ static void singleResize(uiControl *c, intmax_t x, intmax_t y, intmax_t width, i
gtk_widget_size_allocate(S(c)->immediate, &a);
}
// TODO connect free function
static void onDestroy(GtkWidget *widget, gpointer data)
{
uiSingleWidgetControl *c = (uiSingleWidgetControl *) data;
uiFree(c);
}
uiControl *uiUnixNewControl(GType type, gboolean inScrolledWindow, gboolean needsViewport, gboolean scrolledWindowHasBorder, void *data, const char *firstProperty, ...)
{
@ -75,6 +85,19 @@ uiControl *uiUnixNewControl(GType type, gboolean inScrolledWindow, gboolean need
c->immediate = c->scrolledWindow;
}
// we need to keep an extra reference on the immediate widget
// this is so uiControlDestroy() can work regardless of when it is called and who calls it
// without this:
// - end user call works (only one ref)
// - call in uiContainer destructor fails (uiContainer ref freed)
// with this:
// - end user call works (shoudn't be in any container)
// - call in uiContainer works (both refs freed)
g_object_ref_sink(c->immediate);
// and let's free the uiSingleWidgetControl with it
g_signal_connect(c->immediate, "destroy", G_CALLBACK(onDestroy), c);
c->control.destroy = singleDestroy;
c->control.handle = singleHandle;
c->control.setParent = singleSetParent;
c->control.preferredSize = singlePreferredSize;

View File

@ -8,7 +8,7 @@ struct uiWindow {
void *onClosingData;
};
static void onDestroy(GtkWindow *window, gpointer data)
static void onDestroy(GtkWidget *widget, gpointer data)
{
uiWindow *w = (uiWindow *) data;