Cleaned up memory leaks in the GTK+ backend.
This commit is contained in:
parent
f5c8bdd4b3
commit
d37bc67158
|
@ -19,7 +19,13 @@ static void defaultOnClicked(uiControl *c, void *data)
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO destruction
|
static void onDestroy(GtkWidget *widget, gpointer data)
|
||||||
|
{
|
||||||
|
struct button *b = (struct button *) data;
|
||||||
|
|
||||||
|
uiFree(b);
|
||||||
|
}
|
||||||
|
|
||||||
uiControl *uiNewButton(const char *text)
|
uiControl *uiNewButton(const char *text)
|
||||||
{
|
{
|
||||||
struct button *b;
|
struct button *b;
|
||||||
|
@ -33,6 +39,7 @@ uiControl *uiNewButton(const char *text)
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
widget = GTK_WIDGET(uiControlHandle(b->c));
|
widget = GTK_WIDGET(uiControlHandle(b->c));
|
||||||
|
g_signal_connect(widget, "destroy", G_CALLBACK(onDestroy), b);
|
||||||
g_signal_connect(widget, "clicked", G_CALLBACK(onClicked), b);
|
g_signal_connect(widget, "clicked", G_CALLBACK(onClicked), b);
|
||||||
|
|
||||||
b->onClicked = defaultOnClicked;
|
b->onClicked = defaultOnClicked;
|
||||||
|
|
|
@ -15,6 +15,10 @@ static void uiContainer_init(uiContainer *c)
|
||||||
static void uiContainer_dispose(GObject *obj)
|
static void uiContainer_dispose(GObject *obj)
|
||||||
{
|
{
|
||||||
g_ptr_array_unref(uiContainer(obj)->children);
|
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);
|
G_OBJECT_CLASS(uiContainer_parent_class)->dispose(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,11 @@ struct uiSingleWidgetControl {
|
||||||
|
|
||||||
#define S(c) ((uiSingleWidgetControl *) (c))
|
#define S(c) ((uiSingleWidgetControl *) (c))
|
||||||
|
|
||||||
|
static void singleDestroy(uiControl *c)
|
||||||
|
{
|
||||||
|
gtk_widget_destroy(S(c)->immediate);
|
||||||
|
}
|
||||||
|
|
||||||
static uintptr_t singleHandle(uiControl *c)
|
static uintptr_t singleHandle(uiControl *c)
|
||||||
{
|
{
|
||||||
return (uintptr_t) (S(c)->widget);
|
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);
|
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, ...)
|
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;
|
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.handle = singleHandle;
|
||||||
c->control.setParent = singleSetParent;
|
c->control.setParent = singleSetParent;
|
||||||
c->control.preferredSize = singlePreferredSize;
|
c->control.preferredSize = singlePreferredSize;
|
||||||
|
|
|
@ -8,7 +8,7 @@ struct uiWindow {
|
||||||
void *onClosingData;
|
void *onClosingData;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void onDestroy(GtkWindow *window, gpointer data)
|
static void onDestroy(GtkWidget *widget, gpointer data)
|
||||||
{
|
{
|
||||||
uiWindow *w = (uiWindow *) data;
|
uiWindow *w = (uiWindow *) data;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue