Index: gtk/gtkbuilderprivate.h
===================================================================
--- gtk/gtkbuilderprivate.h	(revisione 20262)
+++ gtk/gtkbuilderprivate.h	(copia locale)
@@ -91,12 +91,18 @@ typedef struct {
   const gchar *last_element;
   GtkBuilder *builder;
   gchar *domain;
+  gchar *root_object;
   GSList *stack;
   SubParser *subparser;
   GMarkupParseContext *ctx;
   const gchar *filename;
   GSList *finalizers;
   GSList *custom_finalizers;
+
+  gboolean root_object_found;
+  gboolean root_object_end_found;
+  gint root_object_level;
+  gint cur_object_level;
 } ParserData;
 
 typedef GType (*GTypeGetFunc) (void);
Index: gtk/gtkbuilder.c
===================================================================
--- gtk/gtkbuilder.c	(revisione 20262)
+++ gtk/gtkbuilder.c	(copia locale)
@@ -54,11 +54,13 @@ static GType gtk_builder_real_get_type_f
 enum {
   PROP_0,
   PROP_TRANSLATION_DOMAIN,
+  PROP_ROOT_OBJECT,
 };
 
 struct _GtkBuilderPrivate
 {
   gchar *domain;
+  gchar *root_object;
   GHashTable *objects;
   GSList *delayed_properties;
   GSList *signals;
@@ -98,6 +100,22 @@ gtk_builder_class_init (GtkBuilderClass 
                                                         NULL,
                                                         GTK_PARAM_READWRITE));
 
+ /** 
+  * GtkBuilder:root-object:
+  *
+  * The id of the object to be object to be considered as root when parsing.
+  * Objects outside the root object will be ignored by the builder.
+  *
+  * Since: 2.14
+  */
+  g_object_class_install_property (gobject_class,
+                                   PROP_ROOT_OBJECT,
+                                   g_param_spec_string ("root-object",
+                                                        P_("Root Object"),
+                                                        P_("Id of the root object"),
+                                                        NULL,
+                                                        GTK_PARAM_READWRITE));
+
   g_type_class_add_private (gobject_class, sizeof (GtkBuilderPrivate));
 }
 
@@ -107,6 +125,7 @@ gtk_builder_init (GtkBuilder *builder)
   builder->priv = G_TYPE_INSTANCE_GET_PRIVATE (builder, GTK_TYPE_BUILDER,
                                                GtkBuilderPrivate);
   builder->priv->domain = NULL;
+  builder->priv->root_object = NULL;
   builder->priv->objects = g_hash_table_new_full (g_str_hash, g_str_equal,
                                                   g_free, g_object_unref);
 }
@@ -122,6 +141,7 @@ gtk_builder_finalize (GObject *object)
   GtkBuilderPrivate *priv = GTK_BUILDER (object)->priv;
   
   g_free (priv->domain);
+  g_free (priv->root_object);
   g_free (priv->filename);
   
   g_hash_table_destroy (priv->objects);
@@ -145,6 +165,9 @@ gtk_builder_set_property (GObject      *
     case PROP_TRANSLATION_DOMAIN:
       gtk_builder_set_translation_domain (builder, g_value_get_string (value));
       break;
+    case PROP_ROOT_OBJECT:
+      gtk_builder_set_root_object (builder, g_value_get_string (value));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -164,6 +187,9 @@ gtk_builder_get_property (GObject    *ob
     case PROP_TRANSLATION_DOMAIN:
       g_value_set_string (value, builder->priv->domain);
       break;
+    case PROP_ROOT_OBJECT:
+      g_value_set_string (value, builder->priv->root_object);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -830,6 +856,47 @@ gtk_builder_get_translation_domain (GtkB
   return builder->priv->domain;
 }
 
+/**
+ * gtk_builder_set_root_object:
+ * @builder: a #GtkBuilder
+ * @root_object: id of the root object
+ *
+ * Sets the id of the object to be considered as root when parsing.
+ * Objects outside the @root_object will be ignored by the builder.
+ *
+ * Since: 2.14
+ **/
+void
+gtk_builder_set_root_object (GtkBuilder  *builder,
+                             const gchar *root_object)
+{
+  g_return_if_fail (GTK_IS_BUILDER (builder));
+
+  g_free (builder->priv->root_object);
+  builder->priv->root_object = g_strdup (root_object);
+
+  g_object_notify (G_OBJECT (builder), "root-object");
+}
+
+/**
+ * gtk_builder_get_root_object:
+ * @builder: a #GtkBuilder
+ *
+ * Gets the translation domain of @builder.
+ *
+ * Return value: the id of the object to be used as root when
+ * parsing.
+ *
+ * Since: 2.14
+ **/
+const gchar *
+gtk_builder_get_root_object (GtkBuilder *builder)
+{
+  g_return_val_if_fail (GTK_IS_BUILDER (builder), NULL);
+
+  return builder->priv->root_object;
+}
+
 typedef struct {
   GModule *module;
   gpointer data;
Index: gtk/gtkbuilder.h
===================================================================
--- gtk/gtkbuilder.h	(revisione 20262)
+++ gtk/gtkbuilder.h	(copia locale)
@@ -110,6 +110,9 @@ void         gtk_builder_connect_signals
 void         gtk_builder_set_translation_domain  (GtkBuilder   	*builder,
                                                   const gchar  	*domain);
 const gchar* gtk_builder_get_translation_domain  (GtkBuilder   	*builder);
+void         gtk_builder_set_root_object         (GtkBuilder    *builder,
+                                                  const gchar   *root_object);
+const gchar* gtk_builder_get_root_object         (GtkBuilder    *builder);
 GType        gtk_builder_get_type_from_name      (GtkBuilder   	*builder,
                                                   const char   	*type_name);
 
Index: gtk/gtk.symbols
===================================================================
--- gtk/gtk.symbols	(revisione 20262)
+++ gtk/gtk.symbols	(copia locale)
@@ -444,10 +444,12 @@ gtk_builder_add_from_string
 gtk_builder_error_quark
 gtk_builder_get_object
 gtk_builder_get_objects
+gtk_builder_get_root_object
 gtk_builder_get_translation_domain
 gtk_builder_get_type G_GNUC_CONST
 gtk_builder_get_type_from_name
 gtk_builder_new
+gtk_builder_set_root_object
 gtk_builder_set_translation_domain
 gtk_builder_connect_signals
 gtk_builder_connect_signals_full
Index: gtk/gtkbuilderparser.c
===================================================================
--- gtk/gtkbuilderparser.c	(revisione 20262)
+++ gtk/gtkbuilderparser.c	(copia locale)
@@ -346,6 +346,23 @@ parse_object (ParserData   *data,
       return;
     }
 
+  ++data->cur_object_level;
+
+  /* check if we reached the root object (if it is specified) */
+  if (data->root_object && !data->root_object_found)
+    {
+      if (strcmp (data->root_object, object_id) == 0)
+        {
+          data->root_object_level = data->cur_object_level;
+
+          GTK_NOTE (BUILDER, g_print ("root object found at level %d\n", data->root_object_level));
+
+          data->root_object_found = TRUE;
+        }
+      else
+        return;
+    }
+
   object_info = g_slice_new0 (ObjectInfo);
   object_info->class_name = object_class;
   object_info->id = object_id;
@@ -800,6 +817,12 @@ start_element (GMarkupParseContext *cont
     parse_requires (data, element_name, names, values, error);
   else if (strcmp (element_name, "object") == 0)
     parse_object (data, element_name, names, values, error);
+  else if (data->root_object && !data->root_object_found)
+    {
+      /* If a root object was specified and it was not yet reached,
+       * simply ignore this tag */
+      return;
+    }
   else if (strcmp (element_name, "child") == 0)
     parse_child (data, element_name, names, values, error);
   else if (strcmp (element_name, "property") == 0)
@@ -909,11 +932,33 @@ end_element (GMarkupParseContext *contex
 			 GTK_MAJOR_VERSION, GTK_MINOR_VERSION);
 	}
     }
+  else if (strcmp (element_name, "interface") == 0)
+    {
+    }
+  else if (data->root_object &&
+           (!data->root_object_found || data->root_object_end_found))
+    {
+      /* If a root object was specified and we are outside it,
+       * simply ignore this tag */
+      return;
+    }
   else if (strcmp (element_name, "object") == 0)
     {
       ObjectInfo *object_info = state_pop_info (data, ObjectInfo);
       ChildInfo* child_info = state_peek_info (data, ChildInfo);
 
+      if (data->root_object &&
+          (data->cur_object_level == data->root_object_level))
+        {
+          GTK_NOTE (BUILDER, g_print ("root object end found at level %d\n", data->root_object_level));
+
+          data->root_object_end_found = TRUE;
+        }
+
+      --data->cur_object_level;
+
+      g_assert (data->cur_object_level >= 0);
+
       object_info->object = builder_construct (data, object_info, error);
       if (!object_info->object)
 	{
@@ -975,9 +1020,6 @@ end_element (GMarkupParseContext *contex
       object_info->signals =
         g_slist_prepend (object_info->signals, signal_info);
     }
-  else if (strcmp (element_name, "interface") == 0)
-    {
-    }
   else if (strcmp (element_name, "placeholder") == 0)
     {
     }
@@ -1064,6 +1106,7 @@ _gtk_builder_parser_parse_buffer (GtkBui
   data->builder = builder;
   data->filename = filename;
   data->domain = g_strdup (gtk_builder_get_translation_domain (builder));
+  data->root_object = g_strdup (gtk_builder_get_root_object (builder));
 
   data->ctx = g_markup_parse_context_new (&parser, 
                                           G_MARKUP_TREAT_CDATA_AS_TEXT, 
@@ -1071,7 +1114,16 @@ _gtk_builder_parser_parse_buffer (GtkBui
 
   if (!g_markup_parse_context_parse (data->ctx, buffer, length, error))
     goto out;
-  
+
+  if (data->root_object && !data->root_object_found)
+    {
+      g_set_error (error, GTK_BUILDER_ERROR, 
+                   GTK_BUILDER_ERROR_INVALID_VALUE,
+                   _("Root object not found: '%s'"),
+		   data->root_object);    
+      goto out;
+    }
+
   _gtk_builder_finish (builder);
 
   /* Custom parser_finished */
@@ -1102,6 +1154,7 @@ _gtk_builder_parser_parse_buffer (GtkBui
   g_slist_foreach (data->custom_finalizers, (GFunc)free_subparser, NULL);
   g_slist_free (data->custom_finalizers);
   g_slist_free (data->finalizers);
+  g_free (data->root_object);
   g_free (data->domain);
   g_markup_parse_context_free (data->ctx);
   g_free (data);
Index: docs/reference/gtk/gtk-sections.txt
===================================================================
--- docs/reference/gtk/gtk-sections.txt	(revisione 20262)
+++ docs/reference/gtk/gtk-sections.txt	(copia locale)
@@ -484,6 +484,8 @@ gtk_builder_connect_signals
 gtk_builder_connect_signals_full
 gtk_builder_set_translation_domain
 gtk_builder_get_translation_domain
+gtk_builder_set_root_object
+gtk_builder_get_root_object
 gtk_builder_get_type_from_name
 gtk_builder_value_from_string
 gtk_builder_value_from_string_type
Index: tests/buildertest.c
===================================================================
--- tests/buildertest.c	(revisione 20262)
+++ tests/buildertest.c	(copia locale)
@@ -2124,6 +2124,77 @@ test_requires (void)
 }
 
 
+static void
+test_root_object (void)
+{
+  GtkBuilder *builder;
+  GError *error;
+  const gchar *root;
+  gint ret;
+  GObject *obj;
+  const gchar buffer[] =
+    "<interface>"
+    "  <object class=\"GtkWindow\" id=\"window\">"
+    "    <child>"
+    "      <object class=\"GtkVBox\" id=\"mainbox\">"
+    "        <property name=\"visible\">True</property>"
+    "        <child>"
+    "          <object class=\"GtkLabel\" id=\"label1\">"
+    "            <property name=\"visible\">True</property>"
+    "            <property name=\"label\" translatable=\"no\">first label</property>"
+    "          </object>"
+    "        </child>"
+    "        <child>"
+    "          <object class=\"GtkLabel\" id=\"label2\">"
+    "            <property name=\"visible\">True</property>"
+    "            <property name=\"label\" translatable=\"no\">second label</property>"
+    "          </object>"
+    "          <packing>"
+    "            <property name=\"position\">1</property>"
+    "          </packing>"
+    "        </child>"
+    "      </object>"
+    "    </child>"
+    "  </object>"
+    "<interface/>";
+  
+  builder = gtk_builder_new ();
+  root = gtk_builder_get_root_object (builder);
+  g_assert (root == NULL);
+  g_object_unref (builder);
+
+  builder = gtk_builder_new ();
+  gtk_builder_set_root_object (builder, "test");
+  root = gtk_builder_get_root_object (builder);
+  g_assert (root);
+  g_assert (strcmp (root, "test") == 0);
+  g_object_unref (builder);
+
+  error = NULL;
+  builder = gtk_builder_new ();
+  gtk_builder_set_root_object (builder, "wrong_root");
+  ret = gtk_builder_add_from_string (builder, buffer, -1, &error);
+  g_assert (!ret);
+  g_assert (error != NULL);
+  g_assert (error->domain == GTK_BUILDER_ERROR);
+  g_assert (error->code == GTK_BUILDER_ERROR_INVALID_VALUE);
+  g_object_unref (builder);
+  g_error_free (error);
+
+  error = NULL;
+  builder = gtk_builder_new ();
+  gtk_builder_set_root_object (builder, "mainbox");
+  ret = gtk_builder_add_from_string (builder, buffer, -1, &error);
+  g_assert (ret);
+  g_assert (error == NULL);
+  obj = gtk_builder_get_object (builder, "window");  
+  g_assert (!obj);
+  obj = gtk_builder_get_object (builder, "mainbox");  
+  g_assert (GTK_IS_WIDGET (obj));
+  g_object_unref (builder);
+}
+
+
 static void 
 test_file (const gchar *filename)
 {
@@ -2168,17 +2239,80 @@ test_file (const gchar *filename)
   builder = NULL;
 }
 
+
+static void 
+test_file_with_root (const gchar *filename, const gchar *root)
+{
+  GtkBuilder *builder;
+  GError *error = NULL;
+  GObject *obj;
+
+  builder = gtk_builder_new ();
+  gtk_builder_set_root_object (builder, root);
+
+  if (!gtk_builder_add_from_file (builder, filename, &error))
+    {
+      g_error (error->message);
+      g_error_free (error);
+      return;
+    }
+
+  obj = gtk_builder_get_object (builder, root);
+  if (GTK_IS_DIALOG (obj))
+    {
+      int response;
+
+      g_print ("Running dialog %s.\n",
+               gtk_widget_get_name (GTK_WIDGET (obj)));
+      response = gtk_dialog_run (GTK_DIALOG (obj));
+    }
+  else if (GTK_IS_WINDOW (obj))
+    {
+       g_signal_connect (obj, "destroy", G_CALLBACK (gtk_main_quit), NULL);
+       g_print ("Showing %s.\n",
+                gtk_widget_get_name (GTK_WIDGET (obj)));
+       gtk_widget_show_all (GTK_WIDGET (obj));
+    }
+  else
+    {
+      GtkWidget *dialog;
+
+      dialog = gtk_dialog_new_with_buttons ("Test Builder",
+                                            NULL,
+                                            GTK_DIALOG_MODAL,
+                                            GTK_STOCK_OK,
+                                            GTK_RESPONSE_ACCEPT,
+                                            GTK_STOCK_CANCEL,
+                                            GTK_RESPONSE_REJECT,
+                                            NULL);
+
+      gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
+                         GTK_WIDGET (obj));
+
+      gtk_widget_show_all (dialog);
+      gtk_dialog_run (GTK_DIALOG (dialog));
+    }
+
+  g_object_unref (builder);
+  builder = NULL;
+}
+
 int
 main (int argc, char **argv)
 {
   /* initialize test program */
   gtk_test_init (&argc, &argv);
 
-  if (argc > 1)
+  if (argc == 2)
     {
       test_file (argv[1]);
       return 0;
     }
+  else if (argc == 3)
+    {
+      test_file_with_root (argv[1], argv[2]);
+      return 0;
+    }
 
   g_test_add_func ("/Builder/Parser", test_parser);
   g_test_add_func ("/Builder/Types", test_types);
@@ -2208,6 +2342,7 @@ main (int argc, char **argv)
   g_test_add_func ("/Builder/IconFactory", test_icon_factory);
   g_test_add_func ("/Builder/PangoAttributes", test_pango_attributes);
   g_test_add_func ("/Builder/Requires", test_requires);
+  g_test_add_func ("/Builder/RootObject", test_root_object);
 
   return g_test_run();
 }
