]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtknotebook.c
Stop scrolling when the widget is unmapped. (#168791, Ryan Lortie)
[~andy/gtk] / gtk / gtknotebook.c
index b0d9af43e50d9b8c4530125747e63b2cbb62075e..0c42e2003b658c2098939b47701cf8fd00b208cf 100644 (file)
@@ -24,6 +24,7 @@
  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
  */
 
+#include <config.h>
 #include "gtknotebook.h"
 #include "gtkmain.h"
 #include "gtkmenu.h"
@@ -34,6 +35,8 @@
 #include "gtkintl.h"
 #include "gtkmarshalers.h"
 #include "gtkbindings.h"
+#include "gtkprivate.h"
+#include "gtkalias.h"
 
 
 #define TAB_OVERLAP    2
@@ -158,6 +161,8 @@ static void gtk_notebook_size_allocate       (GtkWidget        *widget,
                                              GtkAllocation    *allocation);
 static gint gtk_notebook_expose              (GtkWidget        *widget,
                                              GdkEventExpose   *event);
+static gboolean gtk_notebook_scroll          (GtkWidget        *widget,
+                                              GdkEventScroll   *event);
 static gint gtk_notebook_button_press        (GtkWidget        *widget,
                                              GdkEventButton   *event);
 static gint gtk_notebook_button_release      (GtkWidget        *widget,
@@ -170,6 +175,8 @@ static gint gtk_notebook_motion_notify       (GtkWidget        *widget,
                                              GdkEventMotion   *event);
 static gint gtk_notebook_focus_in            (GtkWidget        *widget,
                                              GdkEventFocus    *event);
+static gint gtk_notebook_focus_out           (GtkWidget        *widget,
+                                             GdkEventFocus    *event);
 static void gtk_notebook_grab_notify         (GtkWidget          *widget,
                                              gboolean            was_grabbed);
 static void gtk_notebook_state_changed       (GtkWidget          *widget,
@@ -281,6 +288,9 @@ static gboolean focus_tabs_in  (GtkNotebook      *notebook);
 static gboolean focus_child_in (GtkNotebook      *notebook,
                                GtkDirectionType  direction);
 
+static void stop_scrolling (GtkNotebook *notebook);
+
+
 static GtkContainerClass *parent_class = NULL;
 static guint notebook_signals[LAST_SIGNAL] = { 0 };
 
@@ -361,6 +371,7 @@ gtk_notebook_class_init (GtkNotebookClass *class)
   widget_class->size_request = gtk_notebook_size_request;
   widget_class->size_allocate = gtk_notebook_size_allocate;
   widget_class->expose_event = gtk_notebook_expose;
+  widget_class->scroll_event = gtk_notebook_scroll;
   widget_class->button_press_event = gtk_notebook_button_press;
   widget_class->button_release_event = gtk_notebook_button_release;
   widget_class->enter_notify_event = gtk_notebook_enter_notify;
@@ -369,6 +380,7 @@ gtk_notebook_class_init (GtkNotebookClass *class)
   widget_class->grab_notify = gtk_notebook_grab_notify;
   widget_class->state_changed = gtk_notebook_state_changed;
   widget_class->focus_in_event = gtk_notebook_focus_in;
+  widget_class->focus_out_event = gtk_notebook_focus_out;
   widget_class->focus = gtk_notebook_focus;
   widget_class->style_set = gtk_notebook_style_set;
   
@@ -390,157 +402,191 @@ gtk_notebook_class_init (GtkNotebookClass *class)
   g_object_class_install_property (gobject_class,
                                   PROP_PAGE,
                                   g_param_spec_int ("page",
-                                                    _("Page"),
-                                                    _("The index of the current page"),
+                                                    P_("Page"),
+                                                    P_("The index of the current page"),
                                                     0,
                                                     G_MAXINT,
                                                     0,
-                                                    G_PARAM_READWRITE));
+                                                    GTK_PARAM_READWRITE));
   g_object_class_install_property (gobject_class,
                                   PROP_TAB_POS,
-                                  g_param_spec_enum ("tab_pos",
-                                                     _("Tab Position"),
-                                                     _("Which side of the notebook holds the tabs"),
+                                  g_param_spec_enum ("tab-pos",
+                                                     P_("Tab Position"),
+                                                     P_("Which side of the notebook holds the tabs"),
                                                      GTK_TYPE_POSITION_TYPE,
                                                      GTK_POS_TOP,
-                                                     G_PARAM_READWRITE));
+                                                     GTK_PARAM_READWRITE));
   g_object_class_install_property (gobject_class,
                                   PROP_TAB_BORDER,
-                                  g_param_spec_uint ("tab_border",
-                                                     _("Tab Border"),
-                                                     _("Width of the border around the tab labels"),
+                                  g_param_spec_uint ("tab-border",
+                                                     P_("Tab Border"),
+                                                     P_("Width of the border around the tab labels"),
                                                      0,
                                                      G_MAXUINT,
                                                      2,
-                                                     G_PARAM_WRITABLE));
+                                                     GTK_PARAM_WRITABLE));
   g_object_class_install_property (gobject_class,
                                   PROP_TAB_HBORDER,
-                                  g_param_spec_uint ("tab_hborder",
-                                                     _("Horizontal Tab Border"),
-                                                     _("Width of the horizontal border of tab labels"),
+                                  g_param_spec_uint ("tab-hborder",
+                                                     P_("Horizontal Tab Border"),
+                                                     P_("Width of the horizontal border of tab labels"),
                                                      0,
                                                      G_MAXUINT,
                                                      2,
-                                                     G_PARAM_READWRITE));
+                                                     GTK_PARAM_READWRITE));
   g_object_class_install_property (gobject_class,
                                   PROP_TAB_VBORDER,
-                                  g_param_spec_uint ("tab_vborder",
-                                                     _("Vertical Tab Border"),
-                                                     _("Width of the vertical border of tab labels"),
+                                  g_param_spec_uint ("tab-vborder",
+                                                     P_("Vertical Tab Border"),
+                                                     P_("Width of the vertical border of tab labels"),
                                                      0,
                                                      G_MAXUINT,
                                                      2,
-                                                     G_PARAM_READWRITE));
+                                                     GTK_PARAM_READWRITE));
   g_object_class_install_property (gobject_class,
                                   PROP_SHOW_TABS,
-                                  g_param_spec_boolean ("show_tabs",
-                                                        _("Show Tabs"),
-                                                        _("Whether tabs should be shown or not"),
+                                  g_param_spec_boolean ("show-tabs",
+                                                        P_("Show Tabs"),
+                                                        P_("Whether tabs should be shown or not"),
                                                         TRUE,
-                                                        G_PARAM_READWRITE));
+                                                        GTK_PARAM_READWRITE));
   g_object_class_install_property (gobject_class,
                                   PROP_SHOW_BORDER,
-                                  g_param_spec_boolean ("show_border",
-                                                        _("Show Border"),
-                                                        _("Whether the border should be shown or not"),
+                                  g_param_spec_boolean ("show-border",
+                                                        P_("Show Border"),
+                                                        P_("Whether the border should be shown or not"),
                                                         TRUE,
-                                                        G_PARAM_READWRITE));
+                                                        GTK_PARAM_READWRITE));
   g_object_class_install_property (gobject_class,
                                   PROP_SCROLLABLE,
                                   g_param_spec_boolean ("scrollable",
-                                                        _("Scrollable"),
-                                                        _("If TRUE, scroll arrows are added if there are too many tabs to fit"),
+                                                        P_("Scrollable"),
+                                                        P_("If TRUE, scroll arrows are added if there are too many tabs to fit"),
                                                         FALSE,
-                                                        G_PARAM_READWRITE));
+                                                        GTK_PARAM_READWRITE));
   g_object_class_install_property (gobject_class,
                                   PROP_ENABLE_POPUP,
-                                  g_param_spec_boolean ("enable_popup",
-                                                        _("Enable Popup"),
-                                                        _("If TRUE, pressing the right mouse button on the notebook pops up a menu that you can use to go to a page"),
+                                  g_param_spec_boolean ("enable-popup",
+                                                        P_("Enable Popup"),
+                                                        P_("If TRUE, pressing the right mouse button on the notebook pops up a menu that you can use to go to a page"),
                                                         FALSE,
-                                                        G_PARAM_READWRITE));
+                                                        GTK_PARAM_READWRITE));
   g_object_class_install_property (gobject_class,
                                   PROP_HOMOGENEOUS,
                                   g_param_spec_boolean ("homogeneous",
-                                                        _("Homogeneous"),
-                                                        _("Whether tabs should have homogeneous sizes"),
+                                                        P_("Homogeneous"),
+                                                        P_("Whether tabs should have homogeneous sizes"),
                                                         FALSE,
-                                                        G_PARAM_READWRITE));
+                                                        GTK_PARAM_READWRITE));
 
   gtk_container_class_install_child_property (container_class,
                                              CHILD_PROP_TAB_LABEL,
-                                             g_param_spec_string ("tab_label", 
-                                                                  _("Tab label"),
-                                                                  _("The string displayed on the childs tab label"),
+                                             g_param_spec_string ("tab-label", 
+                                                                  P_("Tab label"),
+                                                                  P_("The string displayed on the child's tab label"),
                                                                   NULL,
-                                                                  G_PARAM_READWRITE));
+                                                                  GTK_PARAM_READWRITE));
   gtk_container_class_install_child_property (container_class,
                                              CHILD_PROP_MENU_LABEL,
-                                             g_param_spec_string ("menu_label", 
-                                                                  _("Menu label"), 
-                                                                  _("The string displayed in the childs menu entry"),
+                                             g_param_spec_string ("menu-label", 
+                                                                  P_("Menu label"), 
+                                                                  P_("The string displayed in the child's menu entry"),
                                                                   NULL,
-                                                                  G_PARAM_READWRITE));
+                                                                  GTK_PARAM_READWRITE));
   gtk_container_class_install_child_property (container_class,
                                              CHILD_PROP_POSITION,
                                              g_param_spec_int ("position", 
-                                                               _("Position"), 
-                                                               _("The index of the child in the parent"),
+                                                               P_("Position"), 
+                                                               P_("The index of the child in the parent"),
                                                                -1, G_MAXINT, 0,
-                                                               G_PARAM_READWRITE));
+                                                               GTK_PARAM_READWRITE));
   gtk_container_class_install_child_property (container_class,
                                              CHILD_PROP_TAB_EXPAND,
-                                             g_param_spec_boolean ("tab_expand", 
-                                                                   _("Tab expand"), 
-                                                                   _("Whether to expand the childs tab or not"),
+                                             g_param_spec_boolean ("tab-expand", 
+                                                                   P_("Tab expand"), 
+                                                                   P_("Whether to expand the child's tab or not"),
                                                                    TRUE,
-                                                                   G_PARAM_READWRITE));
+                                                                   GTK_PARAM_READWRITE));
   gtk_container_class_install_child_property (container_class,
                                              CHILD_PROP_TAB_FILL,
-                                             g_param_spec_boolean ("tab_fill", 
-                                                                   _("Tab fill"), 
-                                                                   _("Wheather the childs tab should fill the allocated area or not"),
+                                             g_param_spec_boolean ("tab-fill", 
+                                                                   P_("Tab fill"), 
+                                                                   P_("Whether the child's tab should fill the allocated area or not"),
                                                                    TRUE,
-                                                                   G_PARAM_READWRITE));
+                                                                   GTK_PARAM_READWRITE));
   gtk_container_class_install_child_property (container_class,
                                              CHILD_PROP_TAB_PACK,
-                                             g_param_spec_enum ("tab_pack", 
-                                                                _("Tab pack type"),
-                                                                _("A GtkPackType indicating whether the child is packed with reference to the start or end of the parent"),
+                                             g_param_spec_enum ("tab-pack", 
+                                                                P_("Tab pack type"),
+                                                                P_("A GtkPackType indicating whether the child is packed with reference to the start or end of the parent"),
                                                                 GTK_TYPE_PACK_TYPE, GTK_PACK_START,
-                                                                G_PARAM_READWRITE));
-  
+                                                                GTK_PARAM_READWRITE));
+
+/**
+ * GtkNotebook:has-secondary-backward-stepper:
+ *
+ * The "has-secondary-backward-stepper" property determines whether 
+ * a second backward arrow button is displayed on the opposite end 
+ * of the tab area.
+ *
+ * Since: 2.4
+ */  
   gtk_widget_class_install_style_property (widget_class,
-                                          g_param_spec_boolean ("has_secondary backward_stepper",
-                                                                _("Secondary backward stepper"),
-                                                                _("Display a second backward arrow button on the opposite end of the tab area"),
+                                          g_param_spec_boolean ("has-secondary-backward-stepper",
+                                                                P_("Secondary backward stepper"),
+                                                                P_("Display a second backward arrow button on the opposite end of the tab area"),
                                                                 FALSE,
                                                                 
-                                                                G_PARAM_READABLE));
+                                                                GTK_PARAM_READABLE));
 
+/**
+ * GtkNotebook:has-secondary-forward-stepper:
+ *
+ * The "has-secondary-forward-stepper" property determines whether 
+ * a second forward arrow button is displayed on the opposite end 
+ * of the tab area.
+ *
+ * Since: 2.4
+ */  
   gtk_widget_class_install_style_property (widget_class,
-                                          g_param_spec_boolean ("has_secondary_forward_stepper",
-                                                                _("Secondary forward stepper"),
-                                                                _("Display a second forward arrow button on the opposite end of the tab area"),
+                                          g_param_spec_boolean ("has-secondary-forward-stepper",
+                                                                P_("Secondary forward stepper"),
+                                                                P_("Display a second forward arrow button on the opposite end of the tab area"),
                                                                 FALSE,
                                                                 
-                                                                G_PARAM_READABLE));
+                                                                GTK_PARAM_READABLE));
 
+/**
+ * GtkNotebook:has-backward-stepper:
+ *
+ * The "has-backward-stepper" property determines whether 
+ * the standard backward arrow button is displayed.
+ *
+ * Since: 2.4
+ */  
   gtk_widget_class_install_style_property (widget_class,
-                                          g_param_spec_boolean ("has_backward_stepper",
-                                                                _("Backward stepper"),
-                                                                _("Display the standard backward arrow button"),
+                                          g_param_spec_boolean ("has-backward-stepper",
+                                                                P_("Backward stepper"),
+                                                                P_("Display the standard backward arrow button"),
                                                                 TRUE,
                                                                 
-                                                                   G_PARAM_READABLE));
+                                                                   GTK_PARAM_READABLE));
 
+/**
+ * GtkNotebook:has-forward-stepper:
+ *
+ * The "has-forward-stepper" property determines whether 
+ * the standard forward arrow button is displayed.
+ *
+ * Since: 2.4
+ */  
   gtk_widget_class_install_style_property (widget_class,
-                                          g_param_spec_boolean ("has_forward_stepper",
-                                                                _("Forward stepper"),
-                                                                _("Display the standard forward arrow button"),
+                                          g_param_spec_boolean ("has-forward-stepper",
+                                                                P_("Forward stepper"),
+                                                                P_("Display the standard forward arrow button"),
                                                                 TRUE,
                                                                 
-                                                                   G_PARAM_READABLE));
+                                                                   GTK_PARAM_READABLE));
 
   notebook_signals[SWITCH_PAGE] =
     g_signal_new ("switch_page",
@@ -747,18 +793,43 @@ get_effective_direction (GtkNotebook      *notebook,
   /* Remap the directions into the effective direction it would be for a
    * GTK_POS_TOP notebook
    */
+
 #define D(rest) GTK_DIR_##rest
 
-  static const GtkDirectionType translate_direction[4][6] = {
-    /* LEFT */   { D(TAB_FORWARD),  D(TAB_BACKWARD), D(LEFT), D(RIGHT), D(UP),   D(DOWN) },
+  static const GtkDirectionType translate_direction[2][4][6] = {
+    /* LEFT */   {{ D(TAB_FORWARD),  D(TAB_BACKWARD), D(LEFT), D(RIGHT), D(UP),   D(DOWN) },
     /* RIGHT */  { D(TAB_BACKWARD), D(TAB_FORWARD),  D(LEFT), D(RIGHT), D(DOWN), D(UP)   },
     /* TOP */    { D(TAB_FORWARD),  D(TAB_BACKWARD), D(UP),   D(DOWN),  D(LEFT), D(RIGHT) },
-    /* BOTTOM */ { D(TAB_BACKWARD), D(TAB_FORWARD),  D(DOWN), D(UP),    D(LEFT), D(RIGHT) },
+    /* BOTTOM */ { D(TAB_BACKWARD), D(TAB_FORWARD),  D(DOWN), D(UP),    D(LEFT), D(RIGHT) }},
+    /* LEFT */  {{ D(TAB_BACKWARD), D(TAB_FORWARD),  D(LEFT), D(RIGHT), D(DOWN), D(UP)   },
+    /* RIGHT */  { D(TAB_FORWARD),  D(TAB_BACKWARD), D(LEFT), D(RIGHT), D(UP),   D(DOWN) },
+    /* TOP */    { D(TAB_FORWARD),  D(TAB_BACKWARD), D(UP),   D(DOWN),  D(RIGHT), D(LEFT) },
+    /* BOTTOM */ { D(TAB_BACKWARD), D(TAB_FORWARD),  D(DOWN), D(UP),    D(RIGHT), D(LEFT) }},
   };
 
 #undef D
 
-  return translate_direction[notebook->tab_pos][direction];
+  int text_dir = gtk_widget_get_direction (GTK_WIDGET (notebook)) == GTK_TEXT_DIR_RTL ? 1 : 0;
+
+  return translate_direction[text_dir][notebook->tab_pos][direction];
+}
+
+static gint
+get_effective_tab_pos (GtkNotebook *notebook)
+{
+  if (gtk_widget_get_direction (GTK_WIDGET (notebook)) == GTK_TEXT_DIR_RTL)
+    {
+      switch (notebook->tab_pos) 
+       {
+       case GTK_POS_LEFT:
+         return GTK_POS_RIGHT;
+       case GTK_POS_RIGHT:
+         return GTK_POS_LEFT;
+       default: ;
+       }
+    }
+
+  return notebook->tab_pos;
 }
 
 static void
@@ -771,7 +842,6 @@ gtk_notebook_move_focus_out (GtkNotebook      *notebook,
   if (GTK_CONTAINER (notebook)->focus_child && effective_direction == GTK_DIR_UP)
     if (focus_tabs_in (notebook))
       return;
-  
   if (gtk_widget_is_focus (GTK_WIDGET (notebook)) && effective_direction == GTK_DIR_DOWN)
     if (focus_child_in (notebook, GTK_DIR_TAB_FORWARD))
       return;
@@ -936,6 +1006,7 @@ gtk_notebook_get_property (GObject         *object,
  * gtk_notebook_size_request
  * gtk_notebook_size_allocate
  * gtk_notebook_expose
+ * gtk_notebook_scroll
  * gtk_notebook_button_press
  * gtk_notebook_button_release
  * gtk_notebook_enter_notify
@@ -954,6 +1025,7 @@ gtk_notebook_get_event_window_position (GtkNotebook  *notebook,
   gint border_width = GTK_CONTAINER (notebook)->border_width;
   GtkNotebookPage *visible_page = NULL;
   GList *tmp_list;
+  gint tab_pos = get_effective_tab_pos (notebook);
 
   for (tmp_list = notebook->children; tmp_list; tmp_list = tmp_list->next)
     {
@@ -972,20 +1044,20 @@ gtk_notebook_get_event_window_position (GtkNotebook  *notebook,
          rectangle->x = widget->allocation.x + border_width;
          rectangle->y = widget->allocation.y + border_width;
          
-         switch (notebook->tab_pos)
+         switch (tab_pos)
            {
            case GTK_POS_TOP:
            case GTK_POS_BOTTOM:
              rectangle->width = widget->allocation.width - 2 * border_width;
              rectangle->height = visible_page->requisition.height;
-             if (notebook->tab_pos == GTK_POS_BOTTOM)
+             if (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 = visible_page->requisition.width;
              rectangle->height = widget->allocation.height - 2 * border_width;
-             if (notebook->tab_pos == GTK_POS_RIGHT)
+             if (tab_pos == GTK_POS_RIGHT)
                rectangle->x += widget->allocation.width - 2 * border_width - rectangle->width;
              break;
            }
@@ -1050,6 +1122,8 @@ gtk_notebook_unmap (GtkWidget *widget)
 {
   g_return_if_fail (GTK_IS_NOTEBOOK (widget));
 
+  stop_scrolling (GTK_NOTEBOOK (widget));
+  
   GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
 
   gdk_window_hide (GTK_NOTEBOOK (widget)->event_window);
@@ -1082,9 +1156,9 @@ gtk_notebook_realize (GtkWidget *widget)
   attributes.height = event_window_pos.height;
   attributes.wclass = GDK_INPUT_ONLY;
   attributes.event_mask = gtk_widget_get_events (widget);
-  attributes.event_mask |= (GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK |
-                           GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK);
-
+  attributes.event_mask |= (GDK_BUTTON_PRESS_MASK |
+                           GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK |
+                           GDK_SCROLL_MASK);
   attributes_mask = GDK_WA_X | GDK_WA_Y;
 
   notebook->event_window = gdk_window_new (gtk_widget_get_parent_window (widget), 
@@ -1369,6 +1443,7 @@ gtk_notebook_size_allocate (GtkWidget     *widget,
 {
   GtkNotebook *notebook = GTK_NOTEBOOK (widget);
   gint vis_pages = 0;
+  gint tab_pos = get_effective_tab_pos (notebook);
 
   widget->allocation = *allocation;
   if (GTK_WIDGET_REALIZED (widget))
@@ -1380,7 +1455,8 @@ gtk_notebook_size_allocate (GtkWidget     *widget,
          gdk_window_move_resize (notebook->event_window,
                                  position.x, position.y,
                                  position.width, position.height);
-         gdk_window_show_unraised (notebook->event_window);
+         if (GTK_WIDGET_MAPPED (notebook))
+           gdk_window_show_unraised (notebook->event_window);
        }
       else
        gdk_window_hide (notebook->event_window);
@@ -1409,7 +1485,7 @@ gtk_notebook_size_allocate (GtkWidget     *widget,
 
          if (notebook->show_tabs && notebook->children && notebook->cur_page)
            {
-             switch (notebook->tab_pos)
+             switch (tab_pos)
                {
                case GTK_POS_TOP:
                  child_allocation.y += notebook->cur_page->requisition.height;
@@ -1444,13 +1520,6 @@ gtk_notebook_size_allocate (GtkWidget     *widget,
 
       gtk_notebook_pages_allocate (notebook);
     }
-
-  if ((vis_pages != 0) != notebook->have_visible_child)
-    {
-      notebook->have_visible_child = (vis_pages != 0);
-      if (notebook->show_tabs)
-       gtk_widget_queue_draw (widget);
-    }
 }
 
 static gint
@@ -1604,7 +1673,11 @@ gtk_notebook_do_arrow (GtkNotebook     *notebook,
 {
   GtkWidget *widget = GTK_WIDGET (notebook);
   GtkDirectionType dir;
-  gboolean left = ARROW_IS_LEFT (arrow);
+  gboolean is_rtl, left;
+
+  is_rtl = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
+  left = (ARROW_IS_LEFT (arrow) && !is_rtl) || 
+         (!ARROW_IS_LEFT (arrow) && is_rtl);
   
   if (!notebook->focus_tab ||
       gtk_notebook_search_page (notebook, notebook->focus_tab,
@@ -1613,9 +1686,9 @@ gtk_notebook_do_arrow (GtkNotebook     *notebook,
     {
       if (notebook->tab_pos == GTK_POS_LEFT ||
          notebook->tab_pos == GTK_POS_RIGHT)
-       dir = left ? GTK_DIR_UP : GTK_DIR_DOWN;
+       dir = ARROW_IS_LEFT (arrow) ? GTK_DIR_UP : GTK_DIR_DOWN;
       else
-       dir = left ? GTK_DIR_LEFT : GTK_DIR_RIGHT;
+       dir = ARROW_IS_LEFT (arrow) ? GTK_DIR_LEFT : GTK_DIR_RIGHT;
       gtk_widget_child_focus (widget, dir);
     }
 }
@@ -1626,7 +1699,10 @@ gtk_notebook_arrow_button_press (GtkNotebook      *notebook,
                                 GdkEventButton   *event)
 {
   GtkWidget *widget = GTK_WIDGET (notebook);
-  
+  gboolean is_rtl = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
+  gboolean left = (ARROW_IS_LEFT (arrow) && !is_rtl) || 
+                  (!ARROW_IS_LEFT (arrow) && is_rtl);
+
   if (!GTK_WIDGET_HAS_FOCUS (widget))
     gtk_widget_grab_focus (widget);
   
@@ -1640,7 +1716,7 @@ gtk_notebook_arrow_button_press (GtkNotebook      *notebook,
       if (!notebook->timer)
        {
          notebook->timer = g_timeout_add (NOTEBOOK_INIT_SCROLL_DELAY, 
-                                          (GtkFunction) gtk_notebook_timer, 
+                                          (GSourceFunc) gtk_notebook_timer, 
                                           (gpointer) notebook);
          notebook->need_timer = TRUE;
        }
@@ -1651,7 +1727,7 @@ gtk_notebook_arrow_button_press (GtkNotebook      *notebook,
     gtk_notebook_switch_focus_tab (notebook,
                                   gtk_notebook_search_page (notebook,
                                                             NULL,
-                                                            ARROW_IS_LEFT (arrow) ? STEP_NEXT : STEP_PREV,
+                                                            left ? STEP_NEXT : STEP_PREV,
                                                             TRUE));
   gtk_notebook_redraw_arrows (notebook);
 
@@ -1692,6 +1768,40 @@ get_widget_coordinates (GtkWidget *widget,
     return FALSE;
 }
 
+static gboolean
+gtk_notebook_scroll (GtkWidget      *widget,
+                     GdkEventScroll *event)
+{
+  GtkNotebook *notebook = GTK_NOTEBOOK (widget);
+
+  GtkWidget* child;
+  GtkWidget* originator;
+
+  if (!notebook->cur_page)
+    return FALSE;
+
+  child = notebook->cur_page->child;
+  originator = gtk_get_event_widget ((GdkEvent *)event);
+
+  /* ignore scroll events from the content of the page */
+  if (!originator || gtk_widget_is_ancestor (originator, child))
+    return FALSE;
+  
+  switch (event->direction)
+    {
+    case GDK_SCROLL_RIGHT:
+    case GDK_SCROLL_DOWN:
+      gtk_notebook_next_page (notebook);
+      break;
+    case GDK_SCROLL_LEFT:
+    case GDK_SCROLL_UP:
+      gtk_notebook_prev_page (notebook);
+      break;
+    }
+
+  return TRUE;
+}
+
 static gboolean
 gtk_notebook_button_press (GtkWidget      *widget,
                           GdkEventButton *event)
@@ -1751,8 +1861,6 @@ gtk_notebook_button_press (GtkWidget      *widget,
       children = children->next;
       num++;
     }
-  if (!children && !GTK_WIDGET_HAS_FOCUS (widget))
-    gtk_widget_grab_focus (widget);
   
   return TRUE;
 }
@@ -1893,7 +2001,18 @@ gtk_notebook_focus_in (GtkWidget     *widget,
 {
   GTK_NOTEBOOK (widget)->child_has_focus = FALSE;
 
-  return (* GTK_WIDGET_CLASS (parent_class)->focus_in_event) (widget, event);
+  gtk_notebook_redraw_tabs (GTK_NOTEBOOK (widget));
+  
+  return FALSE;
+}
+
+static gint
+gtk_notebook_focus_out (GtkWidget     *widget,
+                       GdkEventFocus *event)
+{
+  gtk_notebook_redraw_tabs (GTK_NOTEBOOK (widget));
+
+  return FALSE;
 }
 
 static void
@@ -2104,7 +2223,6 @@ gtk_notebook_remove (GtkContainer *container,
   GtkNotebook *notebook;
   GtkNotebookPage *page;
   GList *children;
-  guint page_num;
 
   g_return_if_fail (GTK_IS_NOTEBOOK (container));
   g_return_if_fail (widget != NULL);
@@ -2112,7 +2230,6 @@ gtk_notebook_remove (GtkContainer *container,
   notebook = GTK_NOTEBOOK (container);
 
   children = notebook->children;
-  page_num = 0;
   while (children)
     {
       page = children->data;
@@ -2121,7 +2238,6 @@ gtk_notebook_remove (GtkContainer *container,
          gtk_notebook_real_remove (notebook, children, FALSE);
          break;
        }
-      page_num++;
       children = children->next;
     }
 }
@@ -2356,8 +2472,6 @@ gtk_notebook_forall (GtkContainer *container,
        {
          if (page->tab_label)
            (* callback) (page->tab_label, callback_data);
-         if (page->menu_label)
-           (* callback) (page->menu_label, callback_data);
        }
     }
 }
@@ -2385,6 +2499,7 @@ gtk_notebook_redraw_tabs (GtkNotebook *notebook)
   GtkNotebookPage *page;
   GdkRectangle redraw_rect;
   gint border;
+  gint tab_pos = get_effective_tab_pos (notebook);
 
   widget = GTK_WIDGET (notebook);
   border = GTK_CONTAINER (notebook)->border_width;
@@ -2397,7 +2512,7 @@ gtk_notebook_redraw_tabs (GtkNotebook *notebook)
   redraw_rect.x = border;
   redraw_rect.y = border;
 
-  switch (notebook->tab_pos)
+  switch (tab_pos)
     {
     case GTK_POS_BOTTOM:
       redraw_rect.y = (widget->allocation.height - border -
@@ -2476,7 +2591,7 @@ gtk_notebook_timer (GtkNotebook *notebook)
        {
          notebook->need_timer = FALSE;
          notebook->timer = g_timeout_add (NOTEBOOK_SCROLL_DELAY,
-                                          (GtkFunction) gtk_notebook_timer, 
+                                          (GSourceFunc) gtk_notebook_timer, 
                                           (gpointer) notebook);
        }
       else
@@ -2738,7 +2853,9 @@ gtk_notebook_paint (GtkWidget    *widget,
   gint width, height;
   gint x, y;
   gint border_width = GTK_CONTAINER (widget)->border_width;
-  gint gap_x = 0, gap_width = 0;
+  gint gap_x = 0, gap_width = 0, step = STEP_PREV;
+  gboolean is_rtl;
+  gint tab_pos;
    
   g_return_if_fail (GTK_IS_NOTEBOOK (widget));
   g_return_if_fail (area != NULL);
@@ -2747,6 +2864,8 @@ gtk_notebook_paint (GtkWidget    *widget,
     return;
 
   notebook = GTK_NOTEBOOK (widget);
+  is_rtl = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
+  tab_pos = get_effective_tab_pos (notebook);
 
   if ((!notebook->show_tabs && !notebook->show_border) ||
       !notebook->cur_page || !GTK_WIDGET_VISIBLE (notebook->cur_page->child))
@@ -2771,7 +2890,7 @@ gtk_notebook_paint (GtkWidget    *widget,
     {
       page = notebook->first_tab->data;
 
-      switch (notebook->tab_pos)
+      switch (tab_pos)
        {
        case GTK_POS_TOP:
          y += page->allocation.height + widget->style->ythickness;
@@ -2791,7 +2910,7 @@ gtk_notebook_paint (GtkWidget    *widget,
     }
   else
     {
-      switch (notebook->tab_pos)
+      switch (tab_pos)
        {
        case GTK_POS_TOP:
          y += notebook->cur_page->allocation.height;
@@ -2805,33 +2924,35 @@ gtk_notebook_paint (GtkWidget    *widget,
          break;
        }
 
-      switch (notebook->tab_pos)
+      switch (tab_pos)
        {
        case GTK_POS_TOP:
        case GTK_POS_BOTTOM:
          gap_x = (notebook->cur_page->allocation.x - widget->allocation.x - border_width);
          gap_width = notebook->cur_page->allocation.width;
+         step = is_rtl ? STEP_NEXT : STEP_PREV;
          break;
        case GTK_POS_LEFT:
        case GTK_POS_RIGHT:
          gap_x = (notebook->cur_page->allocation.y - widget->allocation.y - border_width);
          gap_width = notebook->cur_page->allocation.height;
+         step = STEP_PREV;
          break;
        }
-      gtk_paint_box_gap(widget->style, widget->window,
-                       GTK_STATE_NORMAL, GTK_SHADOW_OUT,
-                       area, widget, "notebook",
-                       x, y, width, height,
-                       notebook->tab_pos, gap_x, gap_width);
+      gtk_paint_box_gap (widget->style, widget->window,
+                        GTK_STATE_NORMAL, GTK_SHADOW_OUT,
+                        area, widget, "notebook",
+                        x, y, width, height,
+                        tab_pos, gap_x, gap_width);
     }
 
   showarrow = FALSE;
-  children = gtk_notebook_search_page (notebook, NULL, STEP_PREV, TRUE);
+  children = gtk_notebook_search_page (notebook, NULL, step, TRUE);
   while (children)
     {
       page = children->data;
       children = gtk_notebook_search_page (notebook, children,
-                                          STEP_PREV, TRUE);
+                                          step, TRUE);
       if (!GTK_WIDGET_VISIBLE (page->child))
        continue;
       if (!GTK_WIDGET_MAPPED (page->tab_label))
@@ -2863,6 +2984,7 @@ gtk_notebook_draw_tab (GtkNotebook     *notebook,
   GdkRectangle page_area;
   GtkStateType state_type;
   GtkPositionType gap_side;
+  gint tab_pos = get_effective_tab_pos (notebook);
   
   g_return_if_fail (notebook != NULL);
   g_return_if_fail (page != NULL);
@@ -2883,7 +3005,7 @@ gtk_notebook_draw_tab (GtkNotebook     *notebook,
 
       widget = GTK_WIDGET (notebook);
       gap_side = 0;
-      switch (notebook->tab_pos)
+      switch (tab_pos)
        {
        case GTK_POS_TOP:
          gap_side = GTK_POS_BOTTOM;
@@ -2952,11 +3074,16 @@ gtk_notebook_draw_arrow (GtkNotebook      *notebook,
   GtkWidget *widget;
   GdkRectangle arrow_rect;
   GtkArrowType arrow;
+  gboolean is_rtl, left;
 
   gtk_notebook_get_arrow_rect (notebook, &arrow_rect, nbarrow);
 
   widget = GTK_WIDGET (notebook);
 
+  is_rtl = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
+  left = (ARROW_IS_LEFT (nbarrow) && !is_rtl) ||
+         (!ARROW_IS_LEFT (nbarrow) && is_rtl); 
+
   if (GTK_WIDGET_DRAWABLE (notebook))
     {
       if (notebook->in_child == nbarrow)
@@ -2976,7 +3103,7 @@ gtk_notebook_draw_arrow (GtkNotebook      *notebook,
 
       if (notebook->focus_tab &&
          !gtk_notebook_search_page (notebook, notebook->focus_tab,
-                                    ARROW_IS_LEFT (nbarrow) ? STEP_PREV : STEP_NEXT, TRUE))
+                                     left? STEP_PREV : STEP_NEXT, TRUE))
        {
          shadow_type = GTK_SHADOW_ETCHED_IN;
          state_type = GTK_STATE_INSENSITIVE;
@@ -3018,6 +3145,10 @@ gtk_notebook_pages_allocate (GtkNotebook   *notebook)
   gint n = 1;
   gint old_fill = 0;
   gint new_fill = 0;
+  gint tab_pos = get_effective_tab_pos (notebook);
+  gboolean is_rtl = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL &&
+                    (tab_pos == GTK_POS_TOP || tab_pos == GTK_POS_BOTTOM));
+  gint memo_x;
 
   if (!notebook->show_tabs || !notebook->children || !notebook->cur_page)
     return;
@@ -3025,7 +3156,7 @@ gtk_notebook_pages_allocate (GtkNotebook   *notebook)
   child_allocation.x = widget->allocation.x + container->border_width;
   child_allocation.y = widget->allocation.y + container->border_width;
 
-  switch (notebook->tab_pos)
+  switch (tab_pos)
     {
     case GTK_POS_BOTTOM:
       child_allocation.y = (widget->allocation.y +
@@ -3061,7 +3192,7 @@ gtk_notebook_pages_allocate (GtkNotebook   *notebook)
       else
        focus_tab = gtk_notebook_search_page (notebook, NULL, STEP_NEXT, TRUE);
 
-      switch (notebook->tab_pos)
+      switch (tab_pos)
        {
        case GTK_POS_TOP:
        case GTK_POS_BOTTOM:
@@ -3252,7 +3383,7 @@ gtk_notebook_pages_allocate (GtkNotebook   *notebook)
 
       n = 0;
       children = notebook->children;
-      switch (notebook->tab_pos)
+      switch (tab_pos)
        {
        case GTK_POS_TOP:
        case GTK_POS_BOTTOM:
@@ -3297,7 +3428,22 @@ gtk_notebook_pages_allocate (GtkNotebook   *notebook)
     }
   
   children = notebook->first_tab;
-  i = 1;
+  i = 1; 
+
+  memo_x = child_allocation.x;
+  if (notebook->children && is_rtl)
+     {
+      child_allocation.x = (allocation->x + allocation->width -
+                               container->border_width); 
+      if (showarrow) 
+       {
+         if (notebook->has_after_previous)
+           child_allocation.x -= ARROW_SPACING + ARROW_SIZE;
+         if (notebook->has_after_next)
+           child_allocation.x -= ARROW_SPACING + ARROW_SIZE;
+       }
+     }
+
   while (children)
     {
       if (children == last_child)
@@ -3307,7 +3453,7 @@ gtk_notebook_pages_allocate (GtkNotebook   *notebook)
        }
 
       page = children->data;
-      if (!showarrow && page->pack != GTK_PACK_START)
+      if (!showarrow && page->pack != GTK_PACK_START) 
        break;
       children = gtk_notebook_search_page (notebook, children, STEP_NEXT,TRUE);
       
@@ -3319,12 +3465,14 @@ gtk_notebook_pages_allocate (GtkNotebook   *notebook)
          old_fill = new_fill;
        }
       
-      switch (notebook->tab_pos)
+      switch (tab_pos)
        {
        case GTK_POS_TOP:
        case GTK_POS_BOTTOM:
          child_allocation.width = (page->requisition.width +
                                    TAB_OVERLAP + delta);
+          if (is_rtl)
+             child_allocation.x -= child_allocation.width;
          break;
        case GTK_POS_LEFT:
        case GTK_POS_RIGHT:
@@ -3334,12 +3482,15 @@ gtk_notebook_pages_allocate (GtkNotebook   *notebook)
        }
 
       gtk_notebook_page_allocate (notebook, page, &child_allocation);
-         
-      switch (notebook->tab_pos)
+
+      switch (tab_pos)
        {
        case GTK_POS_TOP:
        case GTK_POS_BOTTOM:
-         child_allocation.x += child_allocation.width - TAB_OVERLAP;
+          if (!is_rtl)
+            child_allocation.x += child_allocation.width - TAB_OVERLAP;
+          else
+             child_allocation.x += TAB_OVERLAP;
          break;
        case GTK_POS_LEFT:
        case GTK_POS_RIGHT:
@@ -3354,12 +3505,16 @@ gtk_notebook_pages_allocate (GtkNotebook   *notebook)
   if (children)
     {
       children = notebook->children;
-      switch (notebook->tab_pos)
+
+      switch (tab_pos)
        {
        case GTK_POS_TOP:
        case GTK_POS_BOTTOM:
-         child_allocation.x = (allocation->x + allocation->width -
-                               container->border_width);
+          if (!is_rtl)
+            child_allocation.x = (allocation->x + allocation->width -
+                                 container->border_width);
+          else
+             child_allocation.x = memo_x; 
          break;
        case GTK_POS_LEFT:
        case GTK_POS_RIGHT:
@@ -3373,8 +3528,8 @@ gtk_notebook_pages_allocate (GtkNotebook   *notebook)
          page = children->data;
          children = children->next;
 
-         if (page->pack != GTK_PACK_END || !GTK_WIDGET_VISIBLE (page->child))
-           continue;
+          if (page->pack != GTK_PACK_END || !GTK_WIDGET_VISIBLE (page->child))
+             continue;
 
          delta = 0;
          if (n && (page->expand || notebook->homogeneous))
@@ -3384,13 +3539,14 @@ gtk_notebook_pages_allocate (GtkNotebook   *notebook)
              old_fill = new_fill;
            }
 
-         switch (notebook->tab_pos)
+         switch (tab_pos)
            {
            case GTK_POS_TOP:
            case GTK_POS_BOTTOM:
              child_allocation.width = (page->requisition.width +
                                        TAB_OVERLAP + delta);
-             child_allocation.x -= child_allocation.width;
+              if (!is_rtl)
+                child_allocation.x -= child_allocation.width;
              break;
            case GTK_POS_LEFT:
            case GTK_POS_RIGHT:
@@ -3402,11 +3558,14 @@ gtk_notebook_pages_allocate (GtkNotebook   *notebook)
 
          gtk_notebook_page_allocate (notebook, page, &child_allocation);
 
-         switch (notebook->tab_pos)
+         switch (tab_pos)
            {
            case GTK_POS_TOP:
            case GTK_POS_BOTTOM:
-             child_allocation.x += TAB_OVERLAP;
+              if (!is_rtl)
+                child_allocation.x += TAB_OVERLAP;
+              else
+                 child_allocation.x += child_allocation.width - TAB_OVERLAP;
              break;
            case GTK_POS_LEFT:
            case GTK_POS_RIGHT:
@@ -3435,63 +3594,19 @@ gtk_notebook_page_allocate (GtkNotebook     *notebook,
   gint ythickness;
   gint padding;
   gint focus_width;
+  gint tab_pos = get_effective_tab_pos (notebook);
 
   gtk_widget_style_get (widget, "focus-line-width", &focus_width, NULL);
   
   xthickness = widget->style->xthickness;
   ythickness = widget->style->ythickness;
 
-  /* If the size of the notebook tabs change, we need to queue
-   * a redraw on the tab area
-   */
-  if ((allocation->width != page->allocation.width) ||
-      (allocation->height != page->allocation.height))
-    {
-      gint x, y, width, height, border_width;
-
-      border_width = GTK_CONTAINER (notebook)->border_width;
-
-      switch (notebook->tab_pos)
-       {
-       case GTK_POS_TOP:
-         width = widget->allocation.width;
-         height = MAX (page->allocation.height, allocation->height) + ythickness;
-         x = 0;                              
-         y = border_width;
-         break;
-
-       case GTK_POS_BOTTOM:
-         width = widget->allocation.width + xthickness;
-         height = MAX (page->allocation.height, allocation->height) + ythickness;
-         x = 0;                              
-         y = widget->allocation.height - height - border_width;
-         break;
-
-       case GTK_POS_LEFT:
-         width = MAX (page->allocation.width, allocation->width) + xthickness;
-         height = widget->allocation.height;
-         x = border_width;
-         y = 0;
-         break;
-
-       case GTK_POS_RIGHT:
-       default:                /* quiet gcc */
-         width = MAX (page->allocation.width, allocation->width) + xthickness;
-         height = widget->allocation.height;
-         x = widget->allocation.width - width - border_width;
-         y = 0;
-         break;
-       }
-
-      gtk_widget_queue_draw_area (widget, x, y, width, height);
-    }
-
   page->allocation = *allocation;
   gtk_widget_get_child_requisition (page->tab_label, &tab_requisition);
 
   if (notebook->cur_page != page)
     {
-      switch (notebook->tab_pos)
+      switch (tab_pos)
        {
        case GTK_POS_TOP:
          page->allocation.y += ythickness;
@@ -3508,7 +3623,7 @@ gtk_notebook_page_allocate (GtkNotebook     *notebook,
        }
     }
 
-  switch (notebook->tab_pos)
+  switch (tab_pos)
     {
     case GTK_POS_TOP:
     case GTK_POS_BOTTOM:
@@ -3530,7 +3645,7 @@ gtk_notebook_page_allocate (GtkNotebook     *notebook,
        }
       child_allocation.y = (notebook->tab_vborder + focus_width +
                            page->allocation.y);
-      if (notebook->tab_pos == GTK_POS_TOP)
+      if (tab_pos == GTK_POS_TOP)
        child_allocation.y += ythickness;
       child_allocation.height = MAX (1, (((gint) page->allocation.height) - ythickness -
                                         2 * (notebook->tab_vborder + focus_width)));
@@ -3552,7 +3667,7 @@ gtk_notebook_page_allocate (GtkNotebook     *notebook,
          child_allocation.height = tab_requisition.height;
        }
       child_allocation.x = page->allocation.x + notebook->tab_hborder + focus_width;
-      if (notebook->tab_pos == GTK_POS_LEFT)
+      if (tab_pos == GTK_POS_LEFT)
        child_allocation.x += xthickness;
       child_allocation.width = MAX (1, (((gint) page->allocation.width) - xthickness -
                                        2 * (notebook->tab_hborder + focus_width)));
@@ -3574,6 +3689,7 @@ gtk_notebook_calc_tabs (GtkNotebook  *notebook,
   GList *children;
   GList *last_list = NULL;
   gboolean pack;
+  gint tab_pos = get_effective_tab_pos (notebook);
 
   if (!start)
     return;
@@ -3585,7 +3701,7 @@ gtk_notebook_calc_tabs (GtkNotebook  *notebook,
 
   while (1)
     {
-      switch (notebook->tab_pos)
+      switch (tab_pos)
        {
        case GTK_POS_TOP:
        case GTK_POS_BOTTOM:
@@ -3753,6 +3869,7 @@ gtk_notebook_page_select (GtkNotebook *notebook,
 {
   GtkNotebookPage *page;
   GtkDirectionType dir = GTK_DIR_DOWN; /* Quiet GCC */
+  gint tab_pos = get_effective_tab_pos (notebook);
 
   g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), FALSE);
 
@@ -3764,7 +3881,7 @@ gtk_notebook_page_select (GtkNotebook *notebook,
 
   if (move_focus)
     {
-      switch (notebook->tab_pos)
+      switch (tab_pos)
        {
        case GTK_POS_TOP:
          dir = GTK_DIR_DOWN;
@@ -4001,17 +4118,20 @@ gtk_notebook_set_tab_vborder_internal (GtkNotebook *notebook,
  *             or %NULL to use the default label, 'page N'.
  * 
  * Appends a page to @notebook.
+ *
+ * Return value: the index (starting from 0) of the appended
+ * page in the notebook, or -1 if function fails
  **/
-void
+gint
 gtk_notebook_append_page (GtkNotebook *notebook,
                          GtkWidget   *child,
                          GtkWidget   *tab_label)
 {
-  g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
-  g_return_if_fail (GTK_IS_WIDGET (child));
-  g_return_if_fail (tab_label == NULL || GTK_IS_WIDGET (tab_label));
+  g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), -1);
+  g_return_val_if_fail (GTK_IS_WIDGET (child), -1);
+  g_return_val_if_fail (tab_label == NULL || GTK_IS_WIDGET (tab_label), -1);
   
-  gtk_notebook_insert_page_menu (notebook, child, tab_label, NULL, -1);
+  return gtk_notebook_insert_page_menu (notebook, child, tab_label, NULL, -1);
 }
 
 /**
@@ -4029,19 +4149,22 @@ gtk_notebook_append_page (GtkNotebook *notebook,
  * 
  * Appends a page to @notebook, specifying the widget to use as the
  * label in the popup menu.
+ *
+ * Return value: the index (starting from 0) of the appended
+ * page in the notebook, or -1 if function fails
  **/
-void
+gint
 gtk_notebook_append_page_menu (GtkNotebook *notebook,
                               GtkWidget   *child,
                               GtkWidget   *tab_label,
                               GtkWidget   *menu_label)
 {
-  g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
-  g_return_if_fail (GTK_IS_WIDGET (child));
-  g_return_if_fail (tab_label == NULL || GTK_IS_WIDGET (tab_label));
-  g_return_if_fail (menu_label == NULL || GTK_IS_WIDGET (menu_label));
+  g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), -1);
+  g_return_val_if_fail (GTK_IS_WIDGET (child), -1);
+  g_return_val_if_fail (tab_label == NULL || GTK_IS_WIDGET (tab_label), -1);
+  g_return_val_if_fail (menu_label == NULL || GTK_IS_WIDGET (menu_label), -1);
   
-  gtk_notebook_insert_page_menu (notebook, child, tab_label, menu_label, -1);
+  return gtk_notebook_insert_page_menu (notebook, child, tab_label, menu_label, -1);
 }
 
 /**
@@ -4052,17 +4175,20 @@ gtk_notebook_append_page_menu (GtkNotebook *notebook,
  *             or %NULL to use the default label, 'page N'.
  *
  * Prepends a page to @notebook.
+ *
+ * Return value: the index (starting from 0) of the prepended
+ * page in the notebook, or -1 if function fails
  **/
-void
+gint
 gtk_notebook_prepend_page (GtkNotebook *notebook,
                           GtkWidget   *child,
                           GtkWidget   *tab_label)
 {
-  g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
-  g_return_if_fail (GTK_IS_WIDGET (child));
-  g_return_if_fail (tab_label == NULL || GTK_IS_WIDGET (tab_label));
+  g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), -1);
+  g_return_val_if_fail (GTK_IS_WIDGET (child), -1);
+  g_return_val_if_fail (tab_label == NULL || GTK_IS_WIDGET (tab_label), -1);
   
-  gtk_notebook_insert_page_menu (notebook, child, tab_label, NULL, 0);
+  return gtk_notebook_insert_page_menu (notebook, child, tab_label, NULL, 0);
 }
 
 /**
@@ -4080,19 +4206,22 @@ gtk_notebook_prepend_page (GtkNotebook *notebook,
  * 
  * Prepends a page to @notebook, specifying the widget to use as the
  * label in the popup menu.
+ *
+ * Return value: the index (starting from 0) of the prepended
+ * page in the notebook, or -1 if function fails
  **/
-void
+gint
 gtk_notebook_prepend_page_menu (GtkNotebook *notebook,
                                GtkWidget   *child,
                                GtkWidget   *tab_label,
                                GtkWidget   *menu_label)
 {
-  g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
-  g_return_if_fail (GTK_IS_WIDGET (child));
-  g_return_if_fail (tab_label == NULL || GTK_IS_WIDGET (tab_label));
-  g_return_if_fail (menu_label == NULL || GTK_IS_WIDGET (menu_label));
+  g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), -1);
+  g_return_val_if_fail (GTK_IS_WIDGET (child), -1);
+  g_return_val_if_fail (tab_label == NULL || GTK_IS_WIDGET (tab_label), -1);
+  g_return_val_if_fail (menu_label == NULL || GTK_IS_WIDGET (menu_label), -1);
   
-  gtk_notebook_insert_page_menu (notebook, child, tab_label, menu_label, 0);
+  return gtk_notebook_insert_page_menu (notebook, child, tab_label, menu_label, 0);
 }
 
 /**
@@ -4104,19 +4233,22 @@ gtk_notebook_prepend_page_menu (GtkNotebook *notebook,
  * @position: the index (starting at 0) at which to insert the page,
  *            or -1 to append the page after all other pages.
  * 
- * Insert a page into @notebook at the given position
+ * Insert a page into @notebook at the given position.
+ *
+ * Return value: the index (starting from 0) of the inserted
+ * page in the notebook, or -1 if function fails
  **/
-void
+gint
 gtk_notebook_insert_page (GtkNotebook *notebook,
                          GtkWidget   *child,
                          GtkWidget   *tab_label,
                          gint         position)
 {
-  g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
-  g_return_if_fail (GTK_IS_WIDGET (child));
-  g_return_if_fail (tab_label == NULL || GTK_IS_WIDGET (tab_label));
+  g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), -1);
+  g_return_val_if_fail (GTK_IS_WIDGET (child), -1);
+  g_return_val_if_fail (tab_label == NULL || GTK_IS_WIDGET (tab_label), -1);
   
-  gtk_notebook_insert_page_menu (notebook, child, tab_label, NULL, position);
+  return gtk_notebook_insert_page_menu (notebook, child, tab_label, NULL, position);
 }
 
 
@@ -4166,8 +4298,11 @@ gtk_notebook_mnemonic_activate_switch_page (GtkWidget *child,
  * 
  * Insert a page into @notebook at the given position, specifying
  * the widget to use as the label in the popup menu.
+ *
+ * Return value: the index (starting from 0) of the inserted
+ * page in the notebook, or -1 if function fails
  **/
-void
+gint
 gtk_notebook_insert_page_menu (GtkNotebook *notebook,
                               GtkWidget   *child,
                               GtkWidget   *tab_label,
@@ -4177,10 +4312,10 @@ gtk_notebook_insert_page_menu (GtkNotebook *notebook,
   GtkNotebookPage *page;
   gint nchildren;
 
-  g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
-  g_return_if_fail (GTK_IS_WIDGET (child));
-  g_return_if_fail (tab_label == NULL || GTK_IS_WIDGET (tab_label));
-  g_return_if_fail (menu_label == NULL || GTK_IS_WIDGET (menu_label));
+  g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), -1);
+  g_return_val_if_fail (GTK_IS_WIDGET (child), -1);
+  g_return_val_if_fail (tab_label == NULL || GTK_IS_WIDGET (tab_label), -1);
+  g_return_val_if_fail (menu_label == NULL || GTK_IS_WIDGET (menu_label), -1);
 
   gtk_widget_freeze_child_notify (child);
   
@@ -4213,7 +4348,7 @@ gtk_notebook_insert_page_menu (GtkNotebook *notebook,
   page->menu_label = menu_label;
   page->expand = FALSE;
   page->fill = TRUE;
-  page->pack = GTK_PACK_START;
+  page->pack = GTK_PACK_START; 
 
   if (!menu_label)
     page->default_menu = TRUE;
@@ -4271,6 +4406,8 @@ gtk_notebook_insert_page_menu (GtkNotebook *notebook,
   gtk_widget_child_notify (child, "menu_label");
   gtk_widget_child_notify (child, "position");
   gtk_widget_thaw_child_notify (child);
+
+  return position;
 }
 
 /**
@@ -5295,7 +5432,7 @@ gtk_notebook_reorder_child (GtkNotebook *notebook,
 
   gtk_widget_freeze_child_notify (child);
 
-  /* Move around the menu items if necesary */
+  /* Move around the menu items if necessary */
   gtk_notebook_child_reordered (notebook, page);
   gtk_widget_child_notify (child, "tab_pack");
   gtk_widget_child_notify (child, "position");
@@ -5305,3 +5442,6 @@ gtk_notebook_reorder_child (GtkNotebook *notebook,
 
   gtk_widget_thaw_child_notify (child);
 }
+
+#define __GTK_NOTEBOOK_C__
+#include "gtkaliasdef.c"