]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtknotebook.c
New static function to set the background of all windows.
[~andy/gtk] / gtk / gtknotebook.c
index 3900fd67bd59a9cd61d18451c5e70409faf19e44..736ad6558085359c90dec42a01903bdd0ee51b8e 100644 (file)
@@ -25,7 +25,6 @@
  */
 
 #include "gtknotebook.h"
-#include "gtksignal.h"
 #include "gtkmain.h"
 #include "gtkmenu.h"
 #include "gtkmenuitem.h"
@@ -180,7 +179,7 @@ static void gtk_notebook_remove              (GtkContainer     *container,
                                              GtkWidget        *widget);
 static void gtk_notebook_set_focus_child     (GtkContainer     *container,
                                              GtkWidget        *child);
-static GtkType gtk_notebook_child_type       (GtkContainer     *container);
+static GType gtk_notebook_child_type       (GtkContainer     *container);
 static void gtk_notebook_forall              (GtkContainer     *container,
                                              gboolean          include_internals,
                                              GtkCallback       callback,
@@ -189,10 +188,9 @@ static void gtk_notebook_forall              (GtkContainer     *container,
 /*** GtkNotebook Private Functions ***/
 static void gtk_notebook_redraw_tabs         (GtkNotebook      *notebook);
 static void gtk_notebook_redraw_arrows       (GtkNotebook      *notebook);
-static void gtk_notebook_focus_changed       (GtkNotebook      *notebook,
-                                             GtkNotebookPage  *old_page);
 static void gtk_notebook_real_remove         (GtkNotebook      *notebook,
-                                             GList            *list);
+                                             GList            *list,
+                                             gboolean          destroying);
 static void gtk_notebook_update_labels       (GtkNotebook      *notebook);
 static gint gtk_notebook_timer               (GtkNotebook      *notebook);
 static gint gtk_notebook_page_compare        (gconstpointer     a,
@@ -251,6 +249,16 @@ static void gtk_notebook_menu_label_unparent (GtkWidget        *widget,
 static void gtk_notebook_menu_detacher       (GtkWidget        *widget,
                                              GtkMenu          *menu);
 
+/*** GtkNotebook Private Setters ***/
+static void gtk_notebook_set_homogeneous_tabs_internal (GtkNotebook *notebook,
+                                                       gboolean     homogeneous);
+static void gtk_notebook_set_tab_border_internal       (GtkNotebook *notebook,
+                                                       guint        border_width);
+static void gtk_notebook_set_tab_hborder_internal      (GtkNotebook *notebook,
+                                                       guint        tab_hborder);
+static void gtk_notebook_set_tab_vborder_internal      (GtkNotebook *notebook,
+                                                       guint        tab_vborder);
+
 static gboolean focus_tabs_in  (GtkNotebook      *notebook);
 static gboolean focus_child_in (GtkNotebook      *notebook,
                                GtkDirectionType  direction);
@@ -258,26 +266,28 @@ static gboolean focus_child_in (GtkNotebook      *notebook,
 static GtkContainerClass *parent_class = NULL;
 static guint notebook_signals[LAST_SIGNAL] = { 0 };
 
-GtkType
+GType
 gtk_notebook_get_type (void)
 {
-  static GtkType notebook_type = 0;
+  static GType notebook_type = 0;
 
   if (!notebook_type)
     {
-      static const GtkTypeInfo notebook_info =
+      static const GTypeInfo notebook_info =
       {
-       "GtkNotebook",
-       sizeof (GtkNotebook),
        sizeof (GtkNotebookClass),
-       (GtkClassInitFunc) gtk_notebook_class_init,
-       (GtkObjectInitFunc) gtk_notebook_init,
-       /* reserved_1 */ NULL,
-        /* reserved_2 */ NULL,
-        (GtkClassInitFunc) NULL,
+       NULL,           /* base_init */
+       NULL,           /* base_finalize */
+       (GClassInitFunc) gtk_notebook_class_init,
+       NULL,           /* class_finalize */
+       NULL,           /* class_data */
+       sizeof (GtkNotebook),
+       0,              /* n_preallocs */
+       (GInstanceInitFunc) gtk_notebook_init,
       };
 
-      notebook_type = gtk_type_unique (gtk_container_get_type (), &notebook_info);
+      notebook_type = g_type_register_static (GTK_TYPE_CONTAINER, "GtkNotebook",
+                                             &notebook_info, 0);
     }
 
   return notebook_type;
@@ -480,17 +490,18 @@ gtk_notebook_class_init (GtkNotebookClass *class)
                                                                 G_PARAM_READWRITE));
   
   notebook_signals[SWITCH_PAGE] =
-    gtk_signal_new ("switch_page",
-                   GTK_RUN_LAST,
-                   GTK_CLASS_TYPE (object_class),
-                   GTK_SIGNAL_OFFSET (GtkNotebookClass, switch_page),
-                   _gtk_marshal_VOID__POINTER_UINT,
-                   GTK_TYPE_NONE, 2,
-                   GTK_TYPE_POINTER,
-                   GTK_TYPE_UINT);
+    g_signal_new ("switch_page",
+                 G_TYPE_FROM_CLASS (gobject_class),
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET (GtkNotebookClass, switch_page),
+                 NULL, NULL,
+                 _gtk_marshal_VOID__POINTER_UINT,
+                 G_TYPE_NONE, 2,
+                 G_TYPE_POINTER,
+                 G_TYPE_UINT);
   notebook_signals[FOCUS_TAB] = 
     g_signal_new ("focus_tab",
-                  G_TYPE_FROM_CLASS (object_class),
+                  G_TYPE_FROM_CLASS (gobject_class),
                   G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                   G_STRUCT_OFFSET (GtkNotebookClass, focus_tab),
                   NULL, NULL,
@@ -499,7 +510,7 @@ gtk_notebook_class_init (GtkNotebookClass *class)
                   GTK_TYPE_NOTEBOOK_TAB);
   notebook_signals[SELECT_PAGE] = 
     g_signal_new ("select_page",
-                  G_TYPE_FROM_CLASS (object_class),
+                  G_TYPE_FROM_CLASS (gobject_class),
                   G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                   G_STRUCT_OFFSET (GtkNotebookClass, select_page),
                   NULL, NULL,
@@ -508,7 +519,7 @@ gtk_notebook_class_init (GtkNotebookClass *class)
                   G_TYPE_BOOLEAN);
   notebook_signals[CHANGE_CURRENT_PAGE] = 
     g_signal_new ("change_current_page",
-                  G_TYPE_FROM_CLASS (object_class),
+                  G_TYPE_FROM_CLASS (gobject_class),
                   G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                   G_STRUCT_OFFSET (GtkNotebookClass, change_current_page),
                   NULL, NULL,
@@ -517,7 +528,7 @@ gtk_notebook_class_init (GtkNotebookClass *class)
                   G_TYPE_INT);
   notebook_signals[MOVE_FOCUS_OUT] =
     g_signal_new ("move_focus_out",
-                  G_TYPE_FROM_CLASS (object_class),
+                  G_TYPE_FROM_CLASS (gobject_class),
                   G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                   G_STRUCT_OFFSET (GtkNotebookClass, move_focus_out),
                   NULL, NULL,
@@ -526,7 +537,7 @@ gtk_notebook_class_init (GtkNotebookClass *class)
                   GTK_TYPE_DIRECTION_TYPE);
   
   
-  binding_set = gtk_binding_set_by_class (object_class);
+  binding_set = gtk_binding_set_by_class (class);
   gtk_binding_entry_add_signal (binding_set,
                                 GDK_space, 0,
                                 "select_page", 1, 
@@ -574,7 +585,7 @@ gtk_notebook_class_init (GtkNotebookClass *class)
 static void
 gtk_notebook_init (GtkNotebook *notebook)
 {
-  GTK_WIDGET_SET_FLAGS (notebook, GTK_CAN_FOCUS | GTK_RECEIVES_DEFAULT);
+  GTK_WIDGET_SET_FLAGS (notebook, GTK_CAN_FOCUS);
   GTK_WIDGET_SET_FLAGS (notebook, GTK_NO_WINDOW);
 
   notebook->cur_page = NULL;
@@ -708,7 +719,7 @@ gtk_notebook_move_focus_out (GtkNotebook      *notebook,
   g_object_ref (notebook);
   
   notebook->focus_out = TRUE;
-  g_signal_emit_by_name (G_OBJECT (toplevel), "move_focus", direction_type);
+  g_signal_emit_by_name (toplevel, "move_focus", direction_type);
   notebook->focus_out = FALSE;
   
   g_object_unref (notebook);
@@ -725,7 +736,7 @@ gtk_notebook_move_focus_out (GtkNotebook      *notebook,
 GtkWidget*
 gtk_notebook_new (void)
 {
-  return GTK_WIDGET (gtk_type_new (gtk_notebook_get_type ()));
+  return g_object_new (GTK_TYPE_NOTEBOOK, NULL);
 }
 
 /* Private GtkObject Methods :
@@ -737,11 +748,21 @@ gtk_notebook_new (void)
 static void
 gtk_notebook_destroy (GtkObject *object)
 {
+  GList *children;
   GtkNotebook *notebook = GTK_NOTEBOOK (object);
   
   if (notebook->menu)
     gtk_notebook_popup_disable (notebook);
 
+  children = notebook->children;
+  while (children)
+    {
+      GList *child = children;
+      children = child->next;
+      
+      gtk_notebook_real_remove (notebook, child, TRUE);
+    }
+  
   GTK_OBJECT_CLASS (parent_class)->destroy (object);
 }
 
@@ -773,7 +794,7 @@ gtk_notebook_set_property (GObject         *object,
        gtk_notebook_popup_disable (notebook);
       break;
     case PROP_HOMOGENEOUS:
-      gtk_notebook_set_homogeneous_tabs (notebook, g_value_get_boolean (value));
+      gtk_notebook_set_homogeneous_tabs_internal (notebook, g_value_get_boolean (value));
       break;  
     case PROP_PAGE:
       gtk_notebook_set_current_page (notebook, g_value_get_int (value));
@@ -782,13 +803,13 @@ gtk_notebook_set_property (GObject         *object,
       gtk_notebook_set_tab_pos (notebook, g_value_get_enum (value));
       break;
     case PROP_TAB_BORDER:
-      gtk_notebook_set_tab_border (notebook, g_value_get_uint (value));
+      gtk_notebook_set_tab_border_internal (notebook, g_value_get_uint (value));
       break;
     case PROP_TAB_HBORDER:
-      gtk_notebook_set_tab_hborder (notebook, g_value_get_uint (value));
+      gtk_notebook_set_tab_hborder_internal (notebook, g_value_get_uint (value));
       break;
     case PROP_TAB_VBORDER:
-      gtk_notebook_set_tab_vborder (notebook, g_value_get_uint (value));
+      gtk_notebook_set_tab_vborder_internal (notebook, g_value_get_uint (value));
       break;
     default:
       break;
@@ -864,13 +885,23 @@ gtk_notebook_get_event_window_position (GtkNotebook  *notebook,
 {
   GtkWidget *widget = GTK_WIDGET (notebook);
   gint border_width = GTK_CONTAINER (notebook)->border_width;
+  GtkNotebookPage *visible_page = NULL;
+  GList *tmp_list;
 
-  if (notebook->show_tabs && notebook->children)
+  for (tmp_list = notebook->children; tmp_list; tmp_list = tmp_list->next)
     {
-      if (rectangle)
+      GtkNotebookPage *page = tmp_list->data;
+      if (GTK_WIDGET_VISIBLE (page->child))
        {
-         GtkNotebookPage *page = notebook->children->data;
+         visible_page = page;
+         break;
+       }
+    }
 
+  if (notebook->show_tabs && visible_page)
+    {
+      if (rectangle)
+       {
          rectangle->x = widget->allocation.x + border_width;
          rectangle->y = widget->allocation.y + border_width;
          
@@ -879,13 +910,13 @@ gtk_notebook_get_event_window_position (GtkNotebook  *notebook,
            case GTK_POS_TOP:
            case GTK_POS_BOTTOM:
              rectangle->width = widget->allocation.width - 2 * border_width;
-             rectangle->height = page->requisition.height;
+             rectangle->height = visible_page->requisition.height;
              if (notebook->tab_pos == GTK_POS_BOTTOM)
                rectangle->y += widget->allocation.height - 2 * border_width - rectangle->height;
              break;
            case GTK_POS_LEFT:
            case GTK_POS_RIGHT:
-             rectangle->width = page->requisition.width;
+             rectangle->width = visible_page->requisition.width;
              rectangle->height = widget->allocation.height - 2 * border_width;
              if (notebook->tab_pos == GTK_POS_RIGHT)
                rectangle->x += widget->allocation.width - 2 * border_width - rectangle->width;
@@ -975,7 +1006,7 @@ gtk_notebook_realize (GtkWidget *widget)
   gtk_notebook_get_event_window_position (notebook, &event_window_pos);
   
   widget->window = gtk_widget_get_parent_window (widget);
-  gdk_window_ref (widget->window);
+  g_object_ref (widget->window);
   
   attributes.window_type = GDK_WINDOW_CHILD;
   attributes.x = event_window_pos.x;
@@ -1583,6 +1614,9 @@ gtk_notebook_button_press (GtkWidget      *widget,
       return TRUE;
     }
 
+  if (event->button != 1)
+    return FALSE;
+  
   num = 0;
   children = notebook->children;
   while (children)
@@ -1596,24 +1630,15 @@ gtk_notebook_button_press (GtkWidget      *widget,
          (x <= (page->allocation.x + page->allocation.width)) &&
          (y <= (page->allocation.y + page->allocation.height)))
        {
-         if (page == notebook->cur_page && notebook->focus_tab &&
-             notebook->focus_tab != children &&
-             GTK_WIDGET_HAS_FOCUS (notebook))
-           {
-             GtkNotebookPage *old_page;
-             
-             notebook->child_has_focus = FALSE;
-             old_page = (GtkNotebookPage *)
-               (notebook->focus_tab->data);
-             gtk_notebook_switch_focus_tab (notebook, children);
-             gtk_notebook_focus_changed (notebook, old_page);
-           }
-         else
-           {
-             gtk_notebook_switch_focus_tab (notebook, children);
-             gtk_widget_grab_focus (widget);
-             gtk_notebook_switch_page (notebook, page, num);
-           }
+         gboolean page_changed = page != notebook->cur_page;
+         gboolean was_focus = gtk_widget_is_focus (widget);
+         
+         gtk_notebook_switch_focus_tab (notebook, children);
+         gtk_widget_grab_focus (widget);
+         
+         if (page_changed && !was_focus)
+           gtk_widget_child_focus (page->child, GTK_DIR_TAB_FORWARD);
+         
          break;
        }
       children = children->next;
@@ -1939,7 +1964,7 @@ gtk_notebook_remove (GtkContainer *container,
       page = children->data;
       if (page->child == widget)
        {
-         gtk_notebook_real_remove (notebook, children);
+         gtk_notebook_real_remove (notebook, children, FALSE);
          break;
        }
       page_num++;
@@ -2183,7 +2208,7 @@ gtk_notebook_forall (GtkContainer *container,
     }
 }
 
-static GtkType
+static GType
 gtk_notebook_child_type (GtkContainer     *container)
 {
   return GTK_TYPE_WIDGET;
@@ -2192,7 +2217,6 @@ gtk_notebook_child_type (GtkContainer     *container)
 /* Private GtkNotebook Functions:
  *
  * gtk_notebook_redraw_tabs
- * gtk_notebook_focus_changed
  * gtk_notebook_real_remove
  * gtk_notebook_update_labels
  * gtk_notebook_timer
@@ -2269,45 +2293,6 @@ gtk_notebook_redraw_arrows (GtkNotebook *notebook)
     }
 }
 
-static void
-gtk_notebook_focus_changed (GtkNotebook     *notebook,
-                            GtkNotebookPage *old_page)
-{
-  g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
-
-  if (GTK_WIDGET_DRAWABLE (notebook) && notebook->show_tabs) 
-    {
-      GdkRectangle area;
-      gint focus_width;
-
-      gtk_widget_style_get (GTK_WIDGET (notebook), "focus-line-width", &focus_width, NULL);
-
-      if (notebook->focus_tab)
-       {
-         GtkNotebookPage *page;
-
-         page = notebook->focus_tab->data;
-
-         area.x = page->tab_label->allocation.x - focus_width;
-         area.y = page->tab_label->allocation.y - focus_width;
-         area.width = page->tab_label->allocation.width + 2 * focus_width;
-         area.height = page->tab_label->allocation.height + 2 * focus_width;
-
-         gtk_notebook_draw_tab (notebook, page, &area);
-       }
-
-      if (old_page)
-       {
-         area.x = old_page->tab_label->allocation.x - focus_width;
-         area.y = old_page->tab_label->allocation.y - focus_width;
-         area.width = old_page->tab_label->allocation.width + 2 * focus_width;
-         area.height = old_page->tab_label->allocation.height + 2 * focus_width;
-
-         gtk_notebook_draw_tab (notebook, old_page, &area);
-       }
-    }
-}
-
 static gint
 gtk_notebook_timer (GtkNotebook *notebook)
 {
@@ -2366,8 +2351,8 @@ gtk_notebook_remove_tab_label (GtkNotebook     *notebook,
   if (page->tab_label)
     {
       if (page->mnemonic_activate_signal)
-       gtk_signal_disconnect (page->tab_label,
-                              page->mnemonic_activate_signal);
+       g_signal_handler_disconnect (page->tab_label,
+                                    page->mnemonic_activate_signal);
       page->mnemonic_activate_signal = 0;
 
       gtk_widget_unparent (page->tab_label);
@@ -2376,7 +2361,8 @@ gtk_notebook_remove_tab_label (GtkNotebook     *notebook,
 
 static void
 gtk_notebook_real_remove (GtkNotebook *notebook,
-                         GList       *list)
+                         GList       *list,
+                         gboolean     destroying)
 {
   GtkNotebookPage *page;
   GList * next_list;
@@ -2389,13 +2375,13 @@ gtk_notebook_real_remove (GtkNotebook *notebook,
   if (notebook->cur_page == list->data)
     { 
       notebook->cur_page = NULL;
-      if (next_list)
+      if (next_list && !destroying)
        gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (next_list), -1);
     }
 
   if (list == notebook->first_tab)
     notebook->first_tab = next_list;
-  if (list == notebook->focus_tab)
+  if (list == notebook->focus_tab && !destroying)
     gtk_notebook_switch_focus_tab (notebook, next_list);
 
   page = list->data;
@@ -2414,7 +2400,7 @@ gtk_notebook_real_remove (GtkNotebook *notebook,
       gtk_widget_queue_resize (notebook->menu);
     }
   if (!page->default_menu)
-    gtk_widget_unref (page->menu_label);
+    g_object_unref (page->menu_label);
   
   notebook->children = g_list_remove_link (notebook->children, list);
   g_list_free (list);
@@ -2769,20 +2755,19 @@ gtk_notebook_draw_tab (GtkNotebook     *notebook,
       if (gtk_widget_intersect (page->tab_label, area, &child_area) &&
           GTK_WIDGET_DRAWABLE (page->tab_label))
         {
-          GdkEventExpose expose_event;
+          GdkEvent *expose_event = gdk_event_new (GDK_EXPOSE);
 
           /* This is a lame hack since all this code needs rewriting anyhow */
           
-          expose_event.window = page->tab_label->window;
-          expose_event.area = child_area;
-          expose_event.region = gdk_region_rectangle (&child_area);
-          expose_event.send_event = TRUE;
-          expose_event.type = GDK_EXPOSE;
-          expose_event.count = 0;
+          expose_event->expose.window = g_object_ref (page->tab_label->window);
+          expose_event->expose.area = child_area;
+          expose_event->expose.region = gdk_region_rectangle (&child_area);
+          expose_event->expose.send_event = TRUE;
+          expose_event->expose.count = 0;
 
-         gtk_container_propagate_expose (GTK_CONTAINER (notebook), page->tab_label, &expose_event);
+         gtk_container_propagate_expose (GTK_CONTAINER (notebook), page->tab_label, (GdkEventExpose *)expose_event);
 
-         gdk_region_destroy (expose_event.region);
+         gdk_event_free (expose_event);
         }
     }
 }
@@ -3354,7 +3339,7 @@ gtk_notebook_page_allocate (GtkNotebook     *notebook,
          break;
        }
 
-      gtk_widget_queue_clear_area (widget, x, y, width, height);
+      gtk_widget_queue_draw_area (widget, x, y, width, height);
     }
 
   page->allocation = *allocation;
@@ -3591,10 +3576,11 @@ gtk_notebook_switch_page (GtkNotebook     *notebook,
   if (page_num < 0)
     page_num = g_list_index (notebook->children, page);
 
-  gtk_signal_emit (GTK_OBJECT (notebook), 
-                  notebook_signals[SWITCH_PAGE], 
-                  page,
-                  page_num);
+  g_signal_emit (notebook,
+                notebook_signals[SWITCH_PAGE],
+                0,
+                page,
+                page_num);
 }
 
 static gint
@@ -3663,9 +3649,12 @@ gtk_notebook_switch_focus_tab (GtkNotebook *notebook,
 
   page = notebook->focus_tab->data;
   if (GTK_WIDGET_MAPPED (page->tab_label))
-    gtk_notebook_focus_changed (notebook, old_page);
+    gtk_notebook_redraw_tabs (notebook);
   else
     gtk_notebook_pages_allocate (notebook);
+  
+  gtk_notebook_switch_page (notebook, page,
+                           g_list_index (notebook->children, page));
 }
 
 static void
@@ -3693,10 +3682,11 @@ gtk_notebook_menu_switch_page (GtkWidget       *widget,
       page_num++;
     }
 
-  gtk_signal_emit (GTK_OBJECT (notebook), 
-                  notebook_signals[SWITCH_PAGE], 
-                  page,
-                  page_num);
+  g_signal_emit (notebook,
+                notebook_signals[SWITCH_PAGE],
+                0,
+                page,
+                page_num);
 }
 
 /* Private GtkNotebook Menu Functions:
@@ -3727,8 +3717,8 @@ gtk_notebook_menu_item_create (GtkNotebook *notebook,
   gtk_container_add (GTK_CONTAINER (menu_item), page->menu_label);
   gtk_menu_shell_insert (GTK_MENU_SHELL (notebook->menu), menu_item,
                         gtk_notebook_real_page_position (notebook, list));
-  gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
-                     GTK_SIGNAL_FUNC (gtk_notebook_menu_switch_page), page);
+  g_signal_connect (menu_item, "activate",
+                   G_CALLBACK (gtk_notebook_menu_switch_page), page);
   if (GTK_WIDGET_VISIBLE (page->child))
     gtk_widget_show (menu_item);
 }
@@ -3755,6 +3745,80 @@ gtk_notebook_menu_detacher (GtkWidget *widget,
   notebook->menu = NULL;
 }
 
+/* Private GtkNotebook Setter Functions:
+ *
+ * gtk_notebook_set_homogeneous_tabs_internal
+ * gtk_notebook_set_tab_border_internal
+ * gtk_notebook_set_tab_hborder_internal
+ * gtk_notebook_set_tab_vborder_internal
+ */
+static void
+gtk_notebook_set_homogeneous_tabs_internal (GtkNotebook *notebook,
+                                           gboolean     homogeneous)
+{
+  g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
+
+  if (homogeneous == notebook->homogeneous)
+    return;
+
+  notebook->homogeneous = homogeneous;
+  gtk_widget_queue_resize (GTK_WIDGET (notebook));
+
+  g_object_notify (G_OBJECT (notebook), "homogeneous");
+}
+
+static void
+gtk_notebook_set_tab_border_internal (GtkNotebook *notebook,
+                                     guint        border_width)
+{
+  g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
+
+  notebook->tab_hborder = border_width;
+  notebook->tab_vborder = border_width;
+
+  if (GTK_WIDGET_VISIBLE (notebook) && notebook->show_tabs)
+    gtk_widget_queue_resize (GTK_WIDGET (notebook));
+
+  g_object_freeze_notify (G_OBJECT (notebook));
+  g_object_notify (G_OBJECT (notebook), "tab_hborder");
+  g_object_notify (G_OBJECT (notebook), "tab_vborder");
+  g_object_thaw_notify (G_OBJECT (notebook));
+}
+
+static void
+gtk_notebook_set_tab_hborder_internal (GtkNotebook *notebook,
+                                      guint        tab_hborder)
+{
+  g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
+
+  if (notebook->tab_hborder == tab_hborder)
+    return;
+
+  notebook->tab_hborder = tab_hborder;
+
+  if (GTK_WIDGET_VISIBLE (notebook) && notebook->show_tabs)
+    gtk_widget_queue_resize (GTK_WIDGET (notebook));
+
+  g_object_notify (G_OBJECT (notebook), "tab_hborder");
+}
+
+static void
+gtk_notebook_set_tab_vborder_internal (GtkNotebook *notebook,
+                                      guint        tab_vborder)
+{
+  g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
+
+  if (notebook->tab_vborder == tab_vborder)
+    return;
+
+  notebook->tab_vborder = tab_vborder;
+
+  if (GTK_WIDGET_VISIBLE (notebook) && notebook->show_tabs)
+    gtk_widget_queue_resize (GTK_WIDGET (notebook));
+
+  g_object_notify (G_OBJECT (notebook), "tab_vborder");
+}
+
 /* Public GtkNotebook Page Insert/Remove Methods :
  *
  * gtk_notebook_append_page
@@ -3991,7 +4055,7 @@ gtk_notebook_insert_page_menu (GtkNotebook *notebook,
     page->default_menu = TRUE;
   else  
     {
-      gtk_widget_ref (page->menu_label);
+      g_object_ref (page->menu_label);
       gtk_object_sink (GTK_OBJECT (page->menu_label));
     }
 
@@ -4029,10 +4093,10 @@ gtk_notebook_insert_page_menu (GtkNotebook *notebook,
 
   if (tab_label)
     page->mnemonic_activate_signal =
-      gtk_signal_connect (GTK_OBJECT (tab_label),
-                         "mnemonic_activate",
-                         (GtkSignalFunc) gtk_notebook_mnemonic_activate_switch_page,
-                         notebook);
+      g_signal_connect (tab_label,
+                       "mnemonic_activate",
+                       G_CALLBACK (gtk_notebook_mnemonic_activate_switch_page),
+                       notebook);
 
   if (notebook->show_tabs && GTK_WIDGET_MAPPED (notebook))
     gdk_window_show_unraised (notebook->event_window);
@@ -4068,13 +4132,13 @@ gtk_notebook_remove_page (GtkNotebook *notebook,
     {
       list = g_list_nth (notebook->children, page_num);
       if (list)
-       gtk_notebook_real_remove (notebook, list);
+       gtk_notebook_real_remove (notebook, list, FALSE);
     }
   else
     {
       list = g_list_last (notebook->children);
       if (list)
-       gtk_notebook_real_remove (notebook, list);
+       gtk_notebook_real_remove (notebook, list, FALSE);
     }
 }
 
@@ -4109,7 +4173,8 @@ gtk_notebook_get_current_page (GtkNotebook *notebook)
 /**
  * gtk_notebook_get_nth_page:
  * @notebook: a #GtkNotebook
- * @page_num: the index of a page in the noteobok
+ * @page_num: the index of a page in the noteobok, or -1
+ *            to get the last page.
  * 
  * Returns the child widget contained in page number @page_num.
  * 
@@ -4121,17 +4186,42 @@ gtk_notebook_get_nth_page (GtkNotebook *notebook,
                           gint         page_num)
 {
   GtkNotebookPage *page;
+  GList *list;
 
   g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), NULL);
 
-  page = g_list_nth_data (notebook->children, page_num);
+  if (page_num >= 0)
+    list = g_list_nth (notebook->children, page_num);
+  else
+    list = g_list_last (notebook->children);
 
-  if (page)
-    return page->child;
+  if (list)
+    {
+      page = list->data;
+      return page->child;
+    }
 
   return NULL;
 }
 
+/**
+ * gtk_notebook_get_n_pages:
+ * @notebook: a #GtkNotebook
+ * 
+ * Gets the number of pages in a notebook.
+ * 
+ * Return value: the number of pages in the notebook.
+ *
+ * Since: 2.2
+ **/
+gint
+gtk_notebook_get_n_pages (GtkNotebook *notebook)
+{
+  g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), 0);
+
+  return g_list_length (notebook->children);
+}
+
 /**
  * gtk_notebook_page_num:
  * @notebook: a #GtkNotebook
@@ -4423,13 +4513,7 @@ gtk_notebook_set_homogeneous_tabs (GtkNotebook *notebook,
 {
   g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
 
-  if (homogeneous == notebook->homogeneous)
-    return;
-
-  notebook->homogeneous = homogeneous;
-  gtk_widget_queue_resize (GTK_WIDGET (notebook));
-
-  g_object_notify (G_OBJECT (notebook), "homogeneous");
+  gtk_notebook_set_homogeneous_tabs_internal (notebook, homogeneous);
 }
 
 /**
@@ -4448,17 +4532,7 @@ gtk_notebook_set_tab_border (GtkNotebook *notebook,
 {
   g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
 
-  notebook->tab_hborder = border_width;
-  notebook->tab_vborder = border_width;
-
-  if (GTK_WIDGET_VISIBLE (notebook) && notebook->show_tabs)
-    gtk_widget_queue_resize (GTK_WIDGET (notebook));
-
-  g_object_freeze_notify (G_OBJECT (notebook));
-  g_object_notify (G_OBJECT (notebook), "tab_hborder");
-  g_object_notify (G_OBJECT (notebook), "tab_vborder");
-  g_object_thaw_notify (G_OBJECT (notebook));
-
+  gtk_notebook_set_tab_border_internal (notebook, border_width);
 }
 
 /**
@@ -4474,15 +4548,7 @@ gtk_notebook_set_tab_hborder (GtkNotebook *notebook,
 {
   g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
 
-  if (notebook->tab_hborder == tab_hborder)
-    return;
-
-  notebook->tab_hborder = tab_hborder;
-
-  if (GTK_WIDGET_VISIBLE (notebook) && notebook->show_tabs)
-    gtk_widget_queue_resize (GTK_WIDGET (notebook));
-
-  g_object_notify (G_OBJECT (notebook), "tab_hborder");
+  gtk_notebook_set_tab_hborder_internal (notebook, tab_hborder);
 }
 
 /**
@@ -4498,15 +4564,7 @@ gtk_notebook_set_tab_vborder (GtkNotebook *notebook,
 {
   g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
 
-  if (notebook->tab_vborder == tab_vborder)
-    return;
-
-  notebook->tab_vborder = tab_vborder;
-
-  if (GTK_WIDGET_VISIBLE (notebook) && notebook->show_tabs)
-    gtk_widget_queue_resize (GTK_WIDGET (notebook));
-
-  g_object_notify (G_OBJECT (notebook), "tab_vborder");
+  gtk_notebook_set_tab_vborder_internal (notebook, tab_vborder);
 }
 
 /**
@@ -4714,10 +4772,10 @@ gtk_notebook_set_tab_label (GtkNotebook *notebook,
 
   if (page->tab_label)
     page->mnemonic_activate_signal =
-      gtk_signal_connect (GTK_OBJECT (page->tab_label),
-                         "mnemonic_activate",
-                         (GtkSignalFunc) gtk_notebook_mnemonic_activate_switch_page,
-                         notebook);
+      g_signal_connect (page->tab_label,
+                       "mnemonic_activate",
+                       G_CALLBACK (gtk_notebook_mnemonic_activate_switch_page),
+                       notebook);
 
   if (notebook->show_tabs && GTK_WIDGET_VISIBLE (child))
     {
@@ -4842,13 +4900,13 @@ gtk_notebook_set_menu_label (GtkNotebook *notebook,
                              page->menu_label->parent);
 
       if (!page->default_menu)
-       gtk_widget_unref (page->menu_label);
+       g_object_unref (page->menu_label);
     }
 
   if (menu_label)
     {
       page->menu_label = menu_label;
-      gtk_widget_ref (page->menu_label);
+      g_object_ref (page->menu_label);
       gtk_object_sink (GTK_OBJECT(page->menu_label));
       page->default_menu = FALSE;
     }