]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkwidgetpath.c
filechooserbutton: Update the combo box even after the dialog is cancelled
[~andy/gtk] / gtk / gtkwidgetpath.c
index d25f55097570fac444e8ba752607e802fe5e3068..855902fd6835e09ebb35d4f9659bb294ab692962 100644 (file)
@@ -12,9 +12,7 @@
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  */
 
 #include "config.h"
@@ -23,6 +21,7 @@
 
 #include "gtkwidget.h"
 #include "gtkwidgetpath.h"
+#include "gtkstylecontextprivate.h"
 
 /**
  * SECTION:gtkwidgetpath
@@ -81,7 +80,7 @@
  **/
 
 G_DEFINE_BOXED_TYPE (GtkWidgetPath, gtk_widget_path,
-                    gtk_widget_path_copy, gtk_widget_path_free)
+                    gtk_widget_path_ref, gtk_widget_path_unref)
 
 
 typedef struct GtkPathElement GtkPathElement;
@@ -92,10 +91,14 @@ struct GtkPathElement
   GQuark name;
   GHashTable *regions;
   GArray *classes;
+  GtkWidgetPath *siblings;
+  guint sibling_index;
 };
 
 struct _GtkWidgetPath
 {
+  volatile guint ref_count;
+
   GArray *elems; /* First element contains the described widget */
 };
 
@@ -115,10 +118,42 @@ gtk_widget_path_new (void)
 
   path = g_slice_new0 (GtkWidgetPath);
   path->elems = g_array_new (FALSE, TRUE, sizeof (GtkPathElement));
+  path->ref_count = 1;
 
   return path;
 }
 
+static void
+gtk_path_element_copy (GtkPathElement       *dest,
+                       const GtkPathElement *src)
+{
+  memset (dest, 0, sizeof (GtkPathElement));
+
+  dest->type = src->type;
+  dest->name = src->name;
+  if (src->siblings)
+    dest->siblings = gtk_widget_path_ref (src->siblings);
+  dest->sibling_index = src->sibling_index;
+
+  if (src->regions)
+    {
+      GHashTableIter iter;
+      gpointer key, value;
+
+      g_hash_table_iter_init (&iter, src->regions);
+      dest->regions = g_hash_table_new (NULL, NULL);
+
+      while (g_hash_table_iter_next (&iter, &key, &value))
+        g_hash_table_insert (dest->regions, key, value);
+    }
+
+  if (src->classes)
+    {
+      dest->classes = g_array_new (FALSE, FALSE, sizeof (GQuark));
+      g_array_append_vals (dest->classes, src->classes->data, src->classes->len);
+    }
+}
+
 /**
  * gtk_widget_path_copy:
  * @path: a #GtkWidgetPath
@@ -139,54 +174,60 @@ gtk_widget_path_copy (const GtkWidgetPath *path)
 
   new_path = gtk_widget_path_new ();
 
+  g_array_set_size (new_path->elems, path->elems->len);
+
   for (i = 0; i < path->elems->len; i++)
     {
-      GtkPathElement *elem, new = { 0 };
+      GtkPathElement *elem, *dest;
 
       elem = &g_array_index (path->elems, GtkPathElement, i);
+      dest = &g_array_index (new_path->elems, GtkPathElement, i);
 
-      new.type = elem->type;
-      new.name = elem->name;
-
-      if (elem->regions)
-        {
-          GHashTableIter iter;
-          gpointer key, value;
+      gtk_path_element_copy (dest, elem);
+    }
 
-          g_hash_table_iter_init (&iter, elem->regions);
-          new.regions = g_hash_table_new (NULL, NULL);
+  return new_path;
+}
 
-          while (g_hash_table_iter_next (&iter, &key, &value))
-            g_hash_table_insert (new.regions, key, value);
-        }
+/**
+ * gtk_widget_path_ref:
+ * @path: a #GtkWidgetPath
+ *
+ * Increments the reference count on @path.
+ *
+ * Returns: @path itself.
+ *
+ * Since: 3.2
+ **/
+GtkWidgetPath *
+gtk_widget_path_ref (GtkWidgetPath *path)
+{
+  g_return_val_if_fail (path != NULL, path);
 
-      if (elem->classes)
-        {
-          new.classes = g_array_new (FALSE, FALSE, sizeof (GQuark));
-          g_array_append_vals (new.classes, elem->classes->data, elem->classes->len);
-        }
+  g_atomic_int_add (&path->ref_count, 1);
 
-      g_array_append_val (new_path->elems, new);
-    }
-
-  return new_path;
+  return path;
 }
 
 /**
- * gtk_widget_path_free:
+ * gtk_widget_path_unref:
  * @path: a #GtkWidgetPath
  *
- * Frees a #GtkWidgetPath.
+ * Decrements the reference count on @path, freeing the structure
+ * if the reference count reaches 0.
  *
- * Since: 3.0
+ * Since: 3.2
  **/
 void
-gtk_widget_path_free (GtkWidgetPath *path)
+gtk_widget_path_unref (GtkWidgetPath *path)
 {
   guint i;
 
   g_return_if_fail (path != NULL);
 
+  if (!g_atomic_int_dec_and_test (&path->ref_count))
+    return;
+
   for (i = 0; i < path->elems->len; i++)
     {
       GtkPathElement *elem;
@@ -198,12 +239,32 @@ gtk_widget_path_free (GtkWidgetPath *path)
 
       if (elem->classes)
         g_array_free (elem->classes, TRUE);
+
+      if (elem->siblings)
+        gtk_widget_path_unref (elem->siblings);
     }
 
   g_array_free (path->elems, TRUE);
   g_slice_free (GtkWidgetPath, path);
 }
 
+/**
+ * gtk_widget_path_free:
+ * @path: a #GtkWidgetPath
+ *
+ * Decrements the reference count on @path, freeing the structure
+ * if the reference count reaches 0.
+ *
+ * Since: 3.0
+ **/
+void
+gtk_widget_path_free (GtkWidgetPath *path)
+{
+  g_return_if_fail (path != NULL);
+
+  gtk_widget_path_unref (path);
+}
+
 /**
  * gtk_widget_path_length:
  * @path: a #GtkWidgetPath
@@ -223,6 +284,99 @@ gtk_widget_path_length (const GtkWidgetPath *path)
   return path->elems->len;
 }
 
+/**
+ * gtk_widget_path_to_string:
+ * @path: the path
+ *
+ * Dumps the widget path into a string representation. It tries to match
+ * the CSS style as closely as possible (Note that there might be paths
+ * that cannot be represented in CSS).
+ *
+ * The main use of this code is for debugging purposes, so that you can
+ * g_print() the path or dump it in a gdb session.
+ *
+ * Returns: A new string describing @path.
+ *
+ * Since: 3.2
+ **/
+char *
+gtk_widget_path_to_string (const GtkWidgetPath *path)
+{
+  GString *string;
+  guint i, j;
+
+  g_return_val_if_fail (path != NULL, NULL);
+
+  string = g_string_new ("");
+
+  for (i = 0; i < path->elems->len; i++)
+    {
+      GtkPathElement *elem;
+
+      elem = &g_array_index (path->elems, GtkPathElement, i);
+
+      if (i > 0)
+        g_string_append_c (string, ' ');
+
+      g_string_append (string, g_type_name (elem->type));
+
+      if (elem->name)
+        {
+          g_string_append_c (string, '(');
+          g_string_append (string, g_quark_to_string (elem->name));
+          g_string_append_c (string, ')');
+        }
+
+
+      if (elem->siblings)
+        g_string_append_printf (string, "[%d/%d]",
+                                elem->sibling_index + 1,
+                                gtk_widget_path_length (elem->siblings));
+
+      if (elem->classes)
+        {
+          for (j = 0; j < elem->classes->len; j++)
+            {
+              g_string_append_c (string, '.');
+              g_string_append (string, g_quark_to_string (g_array_index (elem->classes, GQuark, j)));
+            }
+        }
+
+      if (elem->regions)
+        {
+          GHashTableIter iter;
+          gpointer key, value;
+
+          g_hash_table_iter_init (&iter, elem->regions);
+          while (g_hash_table_iter_next (&iter, &key, &value))
+            {
+              GtkRegionFlags flags = GPOINTER_TO_UINT (value);
+              static const char *flag_names[] = {
+                "even",
+                "odd",
+                "first",
+                "last",
+                "only",
+                "sorted"
+              };
+
+              g_string_append_c (string, ' ');
+              g_string_append (string, g_quark_to_string (GPOINTER_TO_UINT (key)));
+              for (j = 0; j < G_N_ELEMENTS(flag_names); j++)
+                {
+                  if (flags & (1 << j))
+                    {
+                      g_string_append_c (string, ':');
+                      g_string_append (string, flag_names[j]);
+                    }
+                }
+            }
+        }
+    }
+
+  return g_string_free (string, FALSE);
+}
+
 /**
  * gtk_widget_path_prepend_type:
  * @path: a #GtkWidgetPath
@@ -239,7 +393,6 @@ gtk_widget_path_prepend_type (GtkWidgetPath *path,
   GtkPathElement new = { 0 };
 
   g_return_if_fail (path != NULL);
-  g_return_if_fail (g_type_is_a (type, GTK_TYPE_WIDGET));
 
   new.type = type;
   g_array_prepend_val (path->elems, new);
@@ -250,7 +403,7 @@ gtk_widget_path_prepend_type (GtkWidgetPath *path,
  * @path: a #GtkWidgetPath
  * @type: widget type to append
  *
- * Appends a widget type to the widget hierachy represented by @path.
+ * Appends a widget type to the widget hierarchy represented by @path.
  *
  * Returns: the position where the element was inserted
  *
@@ -263,7 +416,6 @@ gtk_widget_path_append_type (GtkWidgetPath *path,
   GtkPathElement new = { 0 };
 
   g_return_val_if_fail (path != NULL, 0);
-  g_return_val_if_fail (g_type_is_a (type, GTK_TYPE_WIDGET), 0);
 
   new.type = type;
   g_array_append_val (path->elems, new);
@@ -272,11 +424,105 @@ gtk_widget_path_append_type (GtkWidgetPath *path,
 }
 
 /**
- * gtk_widget_path_iter_get_widget_type:
+ * gtk_widget_path_append_with_siblings:
+ * @path: the widget path to append to
+ * @siblings: a widget path describing a list of siblings. This path
+ *   may not contain any siblings itself and it must not be modified
+ *   afterwards.
+ * @sibling_index: index into @siblings for where the added element is
+ *   positioned.
+ *
+ * Appends a widget type with all its siblings to the widget hierarchy
+ * represented by @path. Using this function instead of
+ * gtk_widget_path_append_type() will allow the CSS theming to use
+ * sibling matches in selectors and apply :nth-child() pseudo classes.
+ * In turn, it requires a lot more care in widget implementations as
+ * widgets need to make sure to call gtk_widget_reset_style() on all
+ * involved widgets when the @siblings path changes.
+ *
+ * Returns: the position where the element was inserted.
+ *
+ * Since: 3.2
+ **/
+gint
+gtk_widget_path_append_with_siblings (GtkWidgetPath *path,
+                                      GtkWidgetPath *siblings,
+                                      guint          sibling_index)
+{
+  GtkPathElement new;
+
+  g_return_val_if_fail (path != NULL, 0);
+  g_return_val_if_fail (siblings != NULL, 0);
+  g_return_val_if_fail (sibling_index < gtk_widget_path_length (siblings), 0);
+
+  gtk_path_element_copy (&new, &g_array_index (siblings->elems, GtkPathElement, sibling_index));
+  new.siblings = gtk_widget_path_ref (siblings);
+  new.sibling_index = sibling_index;
+  g_array_append_val (path->elems, new);
+
+  return path->elems->len - 1;
+}
+
+/**
+ * gtk_widget_path_iter_get_siblings:
+ * @path: a #GtkWidgetPath
+ * @pos: position to get the siblings for, -1 for the path head
+ *
+ * Returns the list of siblings for the element at @pos. If the element
+ * was not added with siblings, %NULL is returned.
+ *
+ * Returns: %NULL or the list of siblings for the element at @pos.
+ **/
+const GtkWidgetPath *
+gtk_widget_path_iter_get_siblings (const GtkWidgetPath *path,
+                                   gint                 pos)
+{
+  GtkPathElement *elem;
+
+  g_return_val_if_fail (path != NULL, G_TYPE_INVALID);
+  g_return_val_if_fail (path->elems->len != 0, G_TYPE_INVALID);
+
+  if (pos < 0 || pos >= path->elems->len)
+    pos = path->elems->len - 1;
+
+  elem = &g_array_index (path->elems, GtkPathElement, pos);
+  return elem->siblings;
+}
+
+/**
+ * gtk_widget_path_iter_get_sibling_index:
+ * @path: a #GtkWidgetPath
+ * @pos: position to get the sibling index for, -1 for the path head
+ *
+ * Returns the index into the list of siblings for the element at @pos as
+ * returned by gtk_widget_path_iter_get_siblings(). If that function would
+ * return %NULL because the element at @pos has no siblings, this function
+ * will return 0.
+ *
+ * Returns: 0 or the index into the list of siblings for the element at @pos.
+ **/
+guint
+gtk_widget_path_iter_get_sibling_index (const GtkWidgetPath *path,
+                                        gint                 pos)
+{
+  GtkPathElement *elem;
+
+  g_return_val_if_fail (path != NULL, G_TYPE_INVALID);
+  g_return_val_if_fail (path->elems->len != 0, G_TYPE_INVALID);
+
+  if (pos < 0 || pos >= path->elems->len)
+    pos = path->elems->len - 1;
+
+  elem = &g_array_index (path->elems, GtkPathElement, pos);
+  return elem->sibling_index;
+}
+
+/**
+ * gtk_widget_path_iter_get_object_type:
  * @path: a #GtkWidgetPath
- * @pos: position to get the widget type for, -1 for the path head
+ * @pos: position to get the object type for, -1 for the path head
  *
- * Returns the widget #GType that is at position @pos in the widget
+ * Returns the object #GType that is at position @pos in the widget
  * hierarchy defined in @path.
  *
  * Returns: a widget type
@@ -284,7 +530,7 @@ gtk_widget_path_append_type (GtkWidgetPath *path,
  * Since: 3.0
  **/
 GType
-gtk_widget_path_iter_get_widget_type (const GtkWidgetPath *path,
+gtk_widget_path_iter_get_object_type (const GtkWidgetPath *path,
                                       gint                 pos)
 {
   GtkPathElement *elem;
@@ -292,7 +538,7 @@ gtk_widget_path_iter_get_widget_type (const GtkWidgetPath *path,
   g_return_val_if_fail (path != NULL, G_TYPE_INVALID);
   g_return_val_if_fail (path->elems->len != 0, G_TYPE_INVALID);
 
-  if (pos < 0 || pos > path->elems->len)
+  if (pos < 0 || pos >= path->elems->len)
     pos = path->elems->len - 1;
 
   elem = &g_array_index (path->elems, GtkPathElement, pos);
@@ -300,18 +546,18 @@ gtk_widget_path_iter_get_widget_type (const GtkWidgetPath *path,
 }
 
 /**
- * gtk_widget_path_iter_set_widget_type:
+ * gtk_widget_path_iter_set_object_type:
  * @path: a #GtkWidgetPath
  * @pos: position to modify, -1 for the path head
- * @type: widget type to set
+ * @type: object type to set
  *
- * Sets the widget type for a given position in the widget hierarchy
- * defined by @path. @type must be a #GtkWidget derived #GType.
+ * Sets the object type for a given position in the widget hierarchy
+ * defined by @path.
  *
  * Since: 3.0
  **/
 void
-gtk_widget_path_iter_set_widget_type (GtkWidgetPath *path,
+gtk_widget_path_iter_set_object_type (GtkWidgetPath *path,
                                       gint           pos,
                                       GType          type)
 {
@@ -319,9 +565,8 @@ gtk_widget_path_iter_set_widget_type (GtkWidgetPath *path,
 
   g_return_if_fail (path != NULL);
   g_return_if_fail (path->elems->len != 0);
-  g_return_if_fail (g_type_is_a (type, GTK_TYPE_WIDGET));
 
-  if (pos < 0 || pos > path->elems->len)
+  if (pos < 0 || pos >= path->elems->len)
     pos = path->elems->len - 1;
 
   elem = &g_array_index (path->elems, GtkPathElement, pos);
@@ -339,7 +584,7 @@ gtk_widget_path_iter_set_widget_type (GtkWidgetPath *path,
  *
  * Returns: The widget name, or %NULL if none was set.
  **/
-G_CONST_RETURN gchar *
+const gchar *
 gtk_widget_path_iter_get_name (const GtkWidgetPath *path,
                                gint                 pos)
 {
@@ -348,7 +593,7 @@ gtk_widget_path_iter_get_name (const GtkWidgetPath *path,
   g_return_val_if_fail (path != NULL, NULL);
   g_return_val_if_fail (path->elems->len != 0, NULL);
 
-  if (pos < 0 || pos > path->elems->len)
+  if (pos < 0 || pos >= path->elems->len)
     pos = path->elems->len - 1;
 
   elem = &g_array_index (path->elems, GtkPathElement, pos);
@@ -377,7 +622,7 @@ gtk_widget_path_iter_set_name (GtkWidgetPath *path,
   g_return_if_fail (path->elems->len != 0);
   g_return_if_fail (name != NULL);
 
-  if (pos < 0 || pos > path->elems->len)
+  if (pos < 0 || pos >= path->elems->len)
     pos = path->elems->len - 1;
 
   elem = &g_array_index (path->elems, GtkPathElement, pos);
@@ -409,7 +654,7 @@ gtk_widget_path_iter_has_qname (const GtkWidgetPath *path,
   g_return_val_if_fail (path->elems->len != 0, FALSE);
   g_return_val_if_fail (qname != 0, FALSE);
 
-  if (pos < 0 || pos > path->elems->len)
+  if (pos < 0 || pos >= path->elems->len)
     pos = path->elems->len - 1;
 
   elem = &g_array_index (path->elems, GtkPathElement, pos);
@@ -440,7 +685,7 @@ gtk_widget_path_iter_has_name (const GtkWidgetPath *path,
   g_return_val_if_fail (path != NULL, FALSE);
   g_return_val_if_fail (path->elems->len != 0, FALSE);
 
-  if (pos < 0 || pos > path->elems->len)
+  if (pos < 0 || pos >= path->elems->len)
     pos = path->elems->len - 1;
 
   qname = g_quark_try_string (name);
@@ -477,7 +722,7 @@ gtk_widget_path_iter_add_class (GtkWidgetPath *path,
   g_return_if_fail (path->elems->len != 0);
   g_return_if_fail (name != NULL);
 
-  if (pos < 0 || pos > path->elems->len)
+  if (pos < 0 || pos >= path->elems->len)
     pos = path->elems->len - 1;
 
   elem = &g_array_index (path->elems, GtkPathElement, pos);
@@ -534,7 +779,7 @@ gtk_widget_path_iter_remove_class (GtkWidgetPath *path,
   g_return_if_fail (path->elems->len != 0);
   g_return_if_fail (name != NULL);
 
-  if (pos < 0 || pos > path->elems->len)
+  if (pos < 0 || pos >= path->elems->len)
     pos = path->elems->len - 1;
 
   qname = g_quark_try_string (name);
@@ -582,7 +827,7 @@ gtk_widget_path_iter_clear_classes (GtkWidgetPath *path,
   g_return_if_fail (path != NULL);
   g_return_if_fail (path->elems->len != 0);
 
-  if (pos < 0 || pos > path->elems->len)
+  if (pos < 0 || pos >= path->elems->len)
     pos = path->elems->len - 1;
 
   elem = &g_array_index (path->elems, GtkPathElement, pos);
@@ -602,9 +847,9 @@ gtk_widget_path_iter_clear_classes (GtkWidgetPath *path,
  * Returns a list with all the class names defined for the widget
  * at position @pos in the hierarchy defined in @path.
  *
- * Returns: (transfer container) (type utf8): The list of classes,
- *          This is a list of strings, the #GSList contents are
- *          owned by GTK+, but you should use g_slist_free() to
+ * Returns: (transfer container) (element-type utf8): The list of
+ *          classes, This is a list of strings, the #GSList contents
+ *          are owned by GTK+, but you should use g_slist_free() to
  *          free the list itself.
  *
  * Since: 3.0
@@ -620,7 +865,7 @@ gtk_widget_path_iter_list_classes (const GtkWidgetPath *path,
   g_return_val_if_fail (path != NULL, NULL);
   g_return_val_if_fail (path->elems->len != 0, NULL);
 
-  if (pos < 0 || pos > path->elems->len)
+  if (pos < 0 || pos >= path->elems->len)
     pos = path->elems->len - 1;
 
   elem = &g_array_index (path->elems, GtkPathElement, pos);
@@ -664,7 +909,7 @@ gtk_widget_path_iter_has_qclass (const GtkWidgetPath *path,
   g_return_val_if_fail (path->elems->len != 0, FALSE);
   g_return_val_if_fail (qname != 0, FALSE);
 
-  if (pos < 0 || pos > path->elems->len)
+  if (pos < 0 || pos >= path->elems->len)
     pos = path->elems->len - 1;
 
   elem = &g_array_index (path->elems, GtkPathElement, pos);
@@ -711,7 +956,7 @@ gtk_widget_path_iter_has_class (const GtkWidgetPath *path,
   g_return_val_if_fail (path->elems->len != 0, FALSE);
   g_return_val_if_fail (name != NULL, FALSE);
 
-  if (pos < 0 || pos > path->elems->len)
+  if (pos < 0 || pos >= path->elems->len)
     pos = path->elems->len - 1;
 
   qname = g_quark_try_string (name);
@@ -733,6 +978,9 @@ gtk_widget_path_iter_has_class (const GtkWidgetPath *path,
  * the hierarchy defined in @path. See
  * gtk_style_context_add_region().
  *
+ * <note><para>Region names must only contain lowercase letters
+ * and '-', starting always with a lowercase letter.</para></note>
+ *
  * Since: 3.0
  **/
 void
@@ -747,8 +995,9 @@ gtk_widget_path_iter_add_region (GtkWidgetPath  *path,
   g_return_if_fail (path != NULL);
   g_return_if_fail (path->elems->len != 0);
   g_return_if_fail (name != NULL);
+  g_return_if_fail (_gtk_style_context_check_region_name (name));
 
-  if (pos < 0 || pos > path->elems->len)
+  if (pos < 0 || pos >= path->elems->len)
     pos = path->elems->len - 1;
 
   elem = &g_array_index (path->elems, GtkPathElement, pos);
@@ -785,7 +1034,7 @@ gtk_widget_path_iter_remove_region (GtkWidgetPath *path,
   g_return_if_fail (path->elems->len != 0);
   g_return_if_fail (name != NULL);
 
-  if (pos < 0 || pos > path->elems->len)
+  if (pos < 0 || pos >= path->elems->len)
     pos = path->elems->len - 1;
 
   qname = g_quark_try_string (name);
@@ -818,7 +1067,7 @@ gtk_widget_path_iter_clear_regions (GtkWidgetPath *path,
   g_return_if_fail (path != NULL);
   g_return_if_fail (path->elems->len != 0);
 
-  if (pos < 0 || pos > path->elems->len)
+  if (pos < 0 || pos >= path->elems->len)
     pos = path->elems->len - 1;
 
   elem = &g_array_index (path->elems, GtkPathElement, pos);
@@ -835,9 +1084,9 @@ gtk_widget_path_iter_clear_regions (GtkWidgetPath *path,
  * Returns a list with all the region names defined for the widget
  * at position @pos in the hierarchy defined in @path.
  *
- * Returns: (transfer container) (type utf8): The list of regions,
- *          This is a list of strings, the #GSList contents are
- *          owned by GTK+, but you should use g_slist_free() to
+ * Returns: (transfer container) (element-type utf8): The list of
+ *          regions, This is a list of strings, the #GSList contents
+ *          are owned by GTK+, but you should use g_slist_free() to
  *          free the list itself.
  *
  * Since: 3.0
@@ -854,7 +1103,7 @@ gtk_widget_path_iter_list_regions (const GtkWidgetPath *path,
   g_return_val_if_fail (path != NULL, NULL);
   g_return_val_if_fail (path->elems->len != 0, NULL);
 
-  if (pos < 0 || pos > path->elems->len)
+  if (pos < 0 || pos >= path->elems->len)
     pos = path->elems->len - 1;
 
   elem = &g_array_index (path->elems, GtkPathElement, pos);
@@ -902,7 +1151,7 @@ gtk_widget_path_iter_has_qregion (const GtkWidgetPath *path,
   g_return_val_if_fail (path->elems->len != 0, FALSE);
   g_return_val_if_fail (qname != 0, FALSE);
 
-  if (pos < 0 || pos > path->elems->len)
+  if (pos < 0 || pos >= path->elems->len)
     pos = path->elems->len - 1;
 
   elem = &g_array_index (path->elems, GtkPathElement, pos);
@@ -947,7 +1196,7 @@ gtk_widget_path_iter_has_region (const GtkWidgetPath *path,
   g_return_val_if_fail (path->elems->len != 0, FALSE);
   g_return_val_if_fail (name != NULL, FALSE);
 
-  if (pos < 0 || pos > path->elems->len)
+  if (pos < 0 || pos >= path->elems->len)
     pos = path->elems->len - 1;
 
   qname = g_quark_try_string (name);
@@ -959,18 +1208,18 @@ gtk_widget_path_iter_has_region (const GtkWidgetPath *path,
 }
 
 /**
- * gtk_widget_path_get_widget_type:
+ * gtk_widget_path_get_object_type:
  * @path: a #GtkWidget
  *
- * Returns the topmost widget type, that is, the widget type this path
+ * Returns the topmost object type, that is, the object type this path
  * is representing.
  *
- * Returns: The widget type
+ * Returns: The object type
  *
  * Since: 3.0
  **/
 GType
-gtk_widget_path_get_widget_type (const GtkWidgetPath *path)
+gtk_widget_path_get_object_type (const GtkWidgetPath *path)
 {
   GtkPathElement *elem;
 
@@ -1000,7 +1249,6 @@ gtk_widget_path_is_type (const GtkWidgetPath *path,
   GtkPathElement *elem;
 
   g_return_val_if_fail (path != NULL, FALSE);
-  g_return_val_if_fail (g_type_is_a (type, GTK_TYPE_WIDGET), FALSE);
 
   elem = &g_array_index (path->elems, GtkPathElement,
                          path->elems->len - 1);
@@ -1031,7 +1279,6 @@ gtk_widget_path_has_parent (const GtkWidgetPath *path,
   guint i;
 
   g_return_val_if_fail (path != NULL, FALSE);
-  g_return_val_if_fail (g_type_is_a (type, GTK_TYPE_WIDGET), FALSE);
 
   for (i = 0; i < path->elems->len - 1; i++)
     {