diff -rpu libglade-2.4.0/glade/glade-init.c libglade-mods/glade/glade-init.c
--- libglade-2.4.0/glade/glade-init.c	2003-10-21 01:31:33.000000000 -0400
+++ libglade-mods/glade/glade-init.c	2004-12-15 19:18:49.000000000 -0500
@@ -100,7 +100,13 @@ get_module_path (void)
     if (exe_prefix)
 	default_dir = g_build_filename (exe_prefix, "lib", "libglade", "2.0", NULL);
     else
-	default_dir = g_build_filename (GLADE_LIBDIR, "libglade", "2.0", NULL);
+#ifndef G_OS_WIN32
+        default_dir = g_build_filename (GLADE_LIBDIR, "libglade", "2.0", NULL);
+#else
+        default_dir = g_win32_get_package_installation_subdirectory (NULL,
+                                                                     "libglade-2.0-0.dll",
+                                                                     "/lib/libglade/2.0");
+#endif
     
     module_path = g_strconcat (module_path_env ? module_path_env : "",
 			       module_path_env ? G_SEARCHPATH_SEPARATOR_S : "",
diff -rpu libglade-2.4.0/glade/glade-parser.c libglade-mods/glade/glade-parser.c
--- libglade-2.4.0/glade/glade-parser.c	2004-02-10 20:26:01.000000000 -0500
+++ libglade-mods/glade/glade-parser.c	2004-12-14 10:31:08.000000000 -0500
@@ -183,14 +183,14 @@ flush_properties(GladeParseState *state)
     case PROP_WIDGET:
 	if (state->widget->properties)
 	    g_warning("we already read all the props for this key.  Leaking");
-	state->widget->properties = (GladeProperty *)state->props->data;
+	state->widget->properties = (GladePropInfo *)state->props->data;
 	state->widget->n_properties = state->props->len;
 	g_array_free(state->props, FALSE);
 	break;
     case PROP_ATK:
 	if (state->widget->atk_props)
 	    g_warning("we already read all the ATK props for this key.  Leaking");
-	state->widget->atk_props = (GladeProperty *)state->props->data;
+	state->widget->atk_props = (GladePropInfo *)state->props->data;
 	state->widget->n_atk_props = state->props->len;
 	g_array_free(state->props, FALSE);
 	break;
@@ -203,7 +203,7 @@ flush_properties(GladeParseState *state)
 						state->widget->n_children-1];
 	    if (info->properties)
 		g_warning("we already read all the child props for this key.  Leaking");
-	    info->properties = (GladeProperty *)state->props->data;
+	    info->properties = (GladePropInfo *)state->props->data;
 	    info->n_properties = state->props->len;
 	    g_array_free(state->props, FALSE);
 	}
@@ -326,6 +326,8 @@ handle_signal(GladeParseState *state, co
 	    info.handler = alloc_string(state->interface, attrs[i+1]);
 	else if (!strcmp(attrs[i], "after"))
 	    info.after = attrs[i+1][0] == 'y';
+	else if (!strcmp(attrs[i], "lookup"))
+	    info.lookup = attrs[i+1][0] == 'y';
 	else if (!strcmp(attrs[i], "object"))
 	    info.object = alloc_string(state->interface, attrs[i+1]);
 	else if (!strcmp(attrs[i], "last_modification_time"))
@@ -861,7 +863,7 @@ glade_parser_start_element(GladeParseSta
 static void
 glade_parser_end_element(GladeParseState *state, const xmlChar *name)
 {
-    GladeProperty prop;
+    GladePropInfo prop;
 
     GLADE_NOTE(PARSER, g_message("</%s> in state %s",
 				 name, state_names[state->state]));
@@ -904,7 +906,7 @@ glade_parser_end_element(GladeParseState
 	if (strcmp(name, "property") != 0)
 	    g_warning("should find </property> here.  Found </%s>", name);
 	if (!state->props)
-	    state->props = g_array_new(FALSE, FALSE, sizeof(GladeProperty));
+	    state->props = g_array_new(FALSE, FALSE, sizeof(GladePropInfo));
 	prop.name = state->prop_name;
  	if (state->translate_prop && state->content->str[0] != '\0') {
 	    if (state->context_prop) 
@@ -931,7 +933,7 @@ glade_parser_end_element(GladeParseState
 	if (strcmp(name, "atkproperty") != 0)
 	    g_warning("should find </atkproperty> here.  Found </%s>", name);
 	if (!state->props)
-	    state->props = g_array_new(FALSE, FALSE, sizeof(GladeProperty));
+	    state->props = g_array_new(FALSE, FALSE, sizeof(GladePropInfo));
 	prop.name = state->prop_name;
  	if (state->translate_prop && state->content->str[0] != '\0') {
 	    if (state->context_prop) 
@@ -998,7 +1000,7 @@ glade_parser_end_element(GladeParseState
 	if (strcmp(name, "property") != 0)
 	    g_warning("should find </property> here.  Found </%s>", name);
 	if (!state->props)
-	    state->props = g_array_new(FALSE, FALSE, sizeof(GladeProperty));
+	    state->props = g_array_new(FALSE, FALSE, sizeof(GladePropInfo));
 	prop.name = state->prop_name;
  	if (state->translate_prop && state->content->str[0] != '\0') {
 	    if (state->context_prop) 
@@ -1313,6 +1315,8 @@ dump_widget(xmlNode *parent, GladeWidget
 	xmlSetProp(node, "handler", info->signals[i].handler);
 	if (info->signals[i].after)
 	    xmlSetProp(node, "after", "yes");
+	if (info->signals[i].lookup)
+	    xmlSetProp(node, "lookup", "yes");
 	if (info->signals[i].object)
 	    xmlSetProp(node, "object", info->signals[i].object);
 	xmlAddChild(widget, node);
@@ -1334,7 +1338,7 @@ dump_widget(xmlNode *parent, GladeWidget
     }
 
     for (i = 0; i < info->n_children; i++) {
-	xmlNode *child;
+	xmlNode *child, *packing;
 	GladeChildInfo *childinfo = &info->children[i];
 	gint k;
 
@@ -1348,22 +1352,38 @@ dump_widget(xmlNode *parent, GladeWidget
 	xmlNodeAddContent(widget, "\n");
 	xmlNodeAddContent(child, "\n");
 
-	for (k = 0; k < childinfo->n_properties; k++) { 
+	for (j = 0; j < indent + 2; j++)
+	    xmlNodeAddContent(child, "  ");
+	dump_widget(child, childinfo->child, indent + 2);
+	xmlNodeAddContent(child, "\n");
+
+	if (childinfo->n_properties)
+        {
+            for (j = 0; j < indent + 2; j++)
+	        xmlNodeAddContent(child, "  ");
+	    packing = xmlNewNode(NULL, "packing");
+	    xmlAddChild(child, packing);
+	    xmlNodeAddContent(packing, "\n");
+        }
+
+        for (k = 0; k < childinfo->n_properties; k++) { 
 	    xmlNode *node;
 
-	    for (j = 0; j < indent + 2; j++)
-		xmlNodeAddContent(child, "  ");
+	    for (j = 0; j < indent + 3; j++)
+		xmlNodeAddContent(packing, "  ");
 	    node = xmlNewNode(NULL, "property");
-	    xmlSetProp(node, "name", childinfo->properties[i].name);
-	    xmlNodeSetContent(node, childinfo->properties[i].value);
-	    xmlAddChild(child, node);
-	    xmlNodeAddContent(child, "\n");
+	    xmlSetProp(node, "name", childinfo->properties[k].name);
+	    xmlNodeSetContent(node, childinfo->properties[k].value);
+	    xmlAddChild(packing, node);
+	    xmlNodeAddContent(packing, "\n");
 	}
 
-	for (j = 0; j < indent + 2; j++)
-	    xmlNodeAddContent(child, "  ");
-	dump_widget(child, childinfo->child, indent + 2);
-	xmlNodeAddContent(child, "\n");
+	if (childinfo->n_properties)
+        {
+	    for (j = 0; j < indent + 2; j++)
+	        xmlNodeAddContent(packing, "  ");
+            xmlNodeAddContent(child, "\n");
+        }
 
 	for (j = 0; j < indent + 1; j++)
 	    xmlNodeAddContent(child, "  ");
diff -rpu libglade-2.4.0/glade/glade-parser.h libglade-mods/glade/glade-parser.h
--- libglade-2.4.0/glade/glade-parser.h	2003-10-21 01:31:33.000000000 -0400
+++ libglade-mods/glade/glade-parser.h	2004-12-14 10:22:44.000000000 -0500
@@ -28,8 +28,8 @@
 
 G_BEGIN_DECLS
 
-typedef struct _GladeProperty GladeProperty;
-struct _GladeProperty {
+typedef struct _GladePropInfo GladePropInfo;
+struct _GladePropInfo {
     gchar *name;
     gchar *value;
 };
@@ -38,8 +38,10 @@ typedef struct _GladeSignalInfo GladeSig
 struct _GladeSignalInfo {
     gchar *name;
     gchar *handler;
-    gchar *object; /* NULL if this isn't a connect_object signal */
+    gchar *object; /* represents userdata, if lookup is FALSE, then do connect_object with a
+                    * widget looked up by name, otherwise g_module_lookup() */
     guint after : 1;
+    guint lookup : 1;
 };
 
 typedef struct _GladeAtkActionInfo GladeAtkActionInfo;
@@ -70,10 +72,10 @@ struct _GladeWidgetInfo {
     gchar *classname;
     gchar *name;
 
-    GladeProperty *properties;
+    GladePropInfo *properties;
     guint n_properties;
 
-    GladeProperty *atk_props;
+    GladePropInfo *atk_props;
     guint n_atk_props;
 
     GladeSignalInfo *signals;
@@ -93,7 +95,7 @@ struct _GladeWidgetInfo {
 };
 
 struct _GladeChildInfo {
-    GladeProperty *properties;
+    GladePropInfo *properties;
     guint n_properties;
 
     GladeWidgetInfo *child;
diff -rpu libglade-2.4.0/glade/glade-private.h libglade-mods/glade/glade-private.h
--- libglade-2.4.0/glade/glade-private.h	2002-02-05 08:37:46.000000000 -0500
+++ libglade-mods/glade/glade-private.h	2004-12-14 12:01:14.000000000 -0500
@@ -64,6 +64,7 @@ struct _GladeSignalData {
     GObject *signal_object;
     char *signal_name;
     char *connect_object; /* or NULL if there is none */
+    gboolean lookup_userdata;
     gboolean signal_after;
 };
 
diff -rpu libglade-2.4.0/glade/glade-xml.c libglade-mods/glade/glade-xml.c
--- libglade-2.4.0/glade/glade-xml.c	2004-02-10 20:26:02.000000000 -0500
+++ libglade-mods/glade/glade-xml.c	2004-12-15 19:23:59.000000000 -0500
@@ -48,6 +48,11 @@ static GQuark       glade_xml_name_id   
 static const gchar *glade_xml_tooltips_key = "GladeXML::tooltips";
 static GQuark       glade_xml_tooltips_id  = 0;
 
+/* Used for bookkeeping on the name hash */
+typedef struct {
+    gchar    *name;
+    GladeXML *xml;
+} DestroyData;
 
 static void glade_xml_init(GladeXML *xml);
 static void glade_xml_class_init(GladeXMLClass *class);
@@ -277,31 +282,46 @@ autoconnect_foreach(const char *signal_h
 {
     GCallback func;
 
-    if (!g_module_symbol(allsymbols, signal_handler, (gpointer *)&func))
-	g_warning("could not find signal handler '%s'.", signal_handler);
+    if (!g_module_symbol(allsymbols,
+                         signal_handler,
+                         ((gpointer *) &func)))
+        g_warning("could not find signal handler '%s'.", signal_handler);
     else
-	for (; signals != NULL; signals = signals->next) {
-	    GladeSignalData *data = signals->data;
-	    if (data->connect_object) {
-		GladeXML *self = glade_get_widget_tree(
-					GTK_WIDGET(data->signal_object));
-		GObject *other = g_hash_table_lookup(self->priv->name_hash,
-						       data->connect_object);
-
-		g_signal_connect_object(data->signal_object, data->signal_name,
-			func, other, (data->signal_after ? G_CONNECT_AFTER : 0)
-					| G_CONNECT_SWAPPED);
-	    } else {
-		/* the signal_data argument is just a string, but may
-		 * be helpful for someone */
-		if (data->signal_after)
-		    g_signal_connect_after(data->signal_object,
-					   data->signal_name, func, NULL);
-		else
-		    g_signal_connect(data->signal_object, data->signal_name,
-				     func, NULL);
-	    }
-	}
+        for (; signals != NULL; signals = signals->next) {
+            GladeSignalData *data = signals->data;
+            if (data->connect_object && !data->lookup_userdata) {
+                GladeXML *self = glade_get_widget_tree
+                    (GTK_WIDGET(data->signal_object));
+                GObject *other = g_hash_table_lookup(self->priv->name_hash,
+                                                     data->connect_object);
+
+                g_signal_connect_object(data->signal_object, data->signal_name,
+                                        func, other, (data->signal_after ? G_CONNECT_AFTER : 0)
+                                        | G_CONNECT_SWAPPED);
+            } else if (data->connect_object && data->lookup_userdata) {
+                gpointer userdata;
+
+                if (!g_module_symbol(allsymbols, data->connect_object, &userdata))
+                    g_warning("could not find user data '%s' for signal handler '%s'.",
+                              data->connect_object, signal_handler);
+                else if (data->signal_after)
+                    g_signal_connect_after(data->signal_object,
+                                           data->signal_name, func, userdata);
+                else
+                    g_signal_connect(data->signal_object, data->signal_name,
+                                     func, userdata);
+                
+            } else {
+                /* the signal_data argument is just a string, but may
+                 * be helpful for someone */
+                if (data->signal_after)
+                    g_signal_connect_after(data->signal_object,
+                                           data->signal_name, func, NULL);
+                else
+                    g_signal_connect(data->signal_object, data->signal_name,
+                                     func, NULL);
+            }
+        }
 }
 
 /**
@@ -727,8 +747,9 @@ glade_xml_add_signals(GladeXML *xml, Gtk
 	data->signal_object = G_OBJECT(w);
 	data->signal_name = sig->name;
 	data->connect_object = sig->object;
+    data->lookup_userdata = sig->lookup;
 	data->signal_after = sig->after;
-
+    
 	list = g_hash_table_lookup(xml->priv->signals, sig->handler);
 	list = g_list_prepend(list, data);
 	g_hash_table_insert(xml->priv->signals, sig->handler, list);
@@ -1240,7 +1261,7 @@ glade_register_widget(GType type,
     GladeWidgetBuildData *data;
     gpointer old_data;
 
-    g_return_if_fail(g_type_is_a(type, GTK_TYPE_WIDGET));
+    g_return_if_fail(g_type_is_a(type, G_TYPE_OBJECT));
 
     if (glade_build_data_id == 0)
 	glade_build_data_id = g_quark_from_static_string(glade_build_data_key);
@@ -1578,7 +1599,7 @@ glade_xml_set_value_from_string (GladeXM
 typedef struct _CustomPropData CustomPropData;
 struct _CustomPropData {
     GladeApplyCustomPropFunc apply_prop;
-    GladeProperty *prop;
+    GladePropInfo *prop;
 };
 
 /**
@@ -1689,7 +1710,7 @@ glade_standard_build_widget(GladeXML *xm
 
     /* handle deferred properties */
     for (tmp = deferred_props; tmp; tmp = tmp->next) {
-	GladeProperty *prop = tmp->data;
+	GladePropInfo *prop = tmp->data;
 
 	glade_xml_handle_widget_prop(xml, widget, prop->name, prop->value);
     }
@@ -1993,21 +2014,14 @@ glade_xml_handle_internal_child(GladeXML
     glade_xml_set_common_params(self, child, child_info->child);
 }
 
-
 static void
-glade_xml_widget_destroy(GtkObject *object, GladeXML *xml)
+glade_xml_finalize_notify (DestroyData *dd, GObject *was_an_object)
 {
-    gchar *name;
-
-    g_return_if_fail(GTK_IS_OBJECT(object));
-    g_return_if_fail(GLADE_IS_XML(xml));
-
-    name = g_object_get_qdata(G_OBJECT(object), glade_xml_name_id);
-
-    if (!name) return;
-    g_hash_table_remove(xml->priv->name_hash, name);
-    g_object_set_qdata(G_OBJECT(object), glade_xml_tree_id, NULL);
-    g_object_set_qdata(G_OBJECT(object), glade_xml_name_id, NULL);
+    if (dd->xml) {
+        g_hash_table_remove(dd->xml->priv->name_hash, dd->name);
+    }
+    g_free (dd->name);
+    g_free (dd);
 }
 
 /**
@@ -2027,16 +2041,19 @@ glade_xml_set_common_params(GladeXML *se
 			    GladeWidgetInfo *info)
 {
     GList *tmp;
+    DestroyData *dd;
     const GladeWidgetBuildData *data;
     static GQuark visible_id = 0;
-
+    
     /* get the build data */
     data = get_build_data(G_OBJECT_TYPE(widget));
     glade_xml_add_signals(self, widget, info);
     glade_xml_add_accels(self, widget, info);
 
-    gtk_widget_set_name(widget, info->name);
-    glade_xml_add_accessibility_info(self, widget, info);
+    if (GTK_IS_WIDGET (widget)) {
+        gtk_widget_set_name(widget, info->name);
+        glade_xml_add_accessibility_info(self, widget, info);
+    }
 
     /* store this information as data of the widget. */
     g_object_set_qdata(G_OBJECT(widget), glade_xml_tree_id, self);
@@ -2044,61 +2061,59 @@ glade_xml_set_common_params(GladeXML *se
     /* store widgets in hash table, for easy lookup */
     g_hash_table_insert(self->priv->name_hash, info->name, widget);
 
-    /* set up function to remove widget from GladeXML object's
-     * name_hash on destruction. Use connect_object so the handler is
-     * automatically removed on finalization of the GladeXML
-     * object. */
-    g_signal_connect_object(G_OBJECT(widget), "destroy",
-			    G_CALLBACK(glade_xml_widget_destroy),
-			    G_OBJECT(self), 0);
-
+    /* set up function to remove object from GladeXML object's
+     * name_hash on destruction. Use a weak pointer to ensure
+     * that the GladeXML object isn't accessed after its destruction.
+     */
+    dd        = g_new (DestroyData, 1);
+    dd->name  = g_strdup (info->name);
+    dd->xml   = self;
+    g_object_weak_ref (G_OBJECT (widget), (GWeakNotify)glade_xml_finalize_notify, dd);
+    g_object_add_weak_pointer (G_OBJECT (self), (gpointer *)&(dd->xml));
+    
     /* handle any deferred properties using this widget */
     tmp = self->priv->deferred_props;
     while (tmp) {
-	GladeDeferredProperty *dprop = tmp->data;
+        GladeDeferredProperty *dprop = tmp->data;
 
-	if (!strcmp(info->name, dprop->target_name)) {
-	    tmp = tmp->next;
-	    self->priv->deferred_props =
-		g_list_remove(self->priv->deferred_props, dprop);
-
-	    switch (dprop->type) {
-	    case DEFERRED_PROP:
-		g_object_set(G_OBJECT(dprop->d.prop.object),
-			     dprop->d.prop.prop_name, G_OBJECT(widget),
-			     NULL);
-		break;
-	    case DEFERRED_REL:
-		{
-		    AtkObject *target = gtk_widget_get_accessible(widget);
-
-		    add_relation(dprop->d.rel.relation_set,
-				 dprop->d.rel.relation_type, target);
-		    g_object_unref(dprop->d.rel.relation_set);
-		}
-		break;
-	    default:
-		g_warning("unknown deferred property type");
-	    }
-	    g_free(dprop);
-	} else {
-	    tmp = tmp->next;
-	}
+        if (!strcmp(info->name, dprop->target_name)) {
+            tmp = tmp->next;
+            self->priv->deferred_props =
+                g_list_remove(self->priv->deferred_props, dprop);
+
+            switch (dprop->type) {
+            case DEFERRED_PROP:
+                g_object_set(G_OBJECT(dprop->d.prop.object),
+                             dprop->d.prop.prop_name, G_OBJECT(widget),
+                             NULL);
+                break;
+            case DEFERRED_REL:
+                {
+                    AtkObject *target = gtk_widget_get_accessible(widget);
+
+                    add_relation(dprop->d.rel.relation_set,
+                                 dprop->d.rel.relation_type, target);
+                    g_object_unref(dprop->d.rel.relation_set);
+                }
+                break;
+            default:
+                g_warning("unknown deferred property type");
+            }
+            g_free(dprop);
+        } else {
+            tmp = tmp->next;
+        }
     }
 
     if (data && data->build_children && info->children) {
-	if (GTK_IS_CONTAINER (widget))
-	    data->build_children(self, widget, info);
-	else
-	    g_warning ("widget %s (%s) has children, but is not a GtkContainer.",
-		       info->name, g_type_name (G_TYPE_FROM_INSTANCE (widget)));
+        data->build_children(self, widget, info);
     }
 
     if (visible_id == 0)
-	visible_id = g_quark_from_static_string("Libglade::visible");
+        visible_id = g_quark_from_static_string("Libglade::visible");
 
     if (g_object_get_qdata(G_OBJECT(widget), visible_id))
-	gtk_widget_show(widget);
+        gtk_widget_show(widget);
 }
 
 /**
