Index: gtk/gtknotebook.c
===================================================================
--- gtk/gtknotebook.c	(revision 17233)
+++ gtk/gtknotebook.c	(working copy)
@@ -179,6 +179,8 @@ struct _GtkNotebookPrivate
 
   guint32 timestamp;
 
+  GtkWidget *action_widget;
+
   guint during_reorder : 1;
   guint during_detach  : 1;
   guint has_scrolled   : 1;
@@ -1496,11 +1498,13 @@ static gboolean
 gtk_notebook_get_event_window_position (GtkNotebook  *notebook,
 					GdkRectangle *rectangle)
 {
+  GtkNotebookPrivate *priv = GTK_NOTEBOOK_GET_PRIVATE (notebook);
   GtkWidget *widget = GTK_WIDGET (notebook);
   gint border_width = GTK_CONTAINER (notebook)->border_width;
   GtkNotebookPage *visible_page = NULL;
   GList *tmp_list;
   gint tab_pos = get_effective_tab_pos (notebook);
+  gboolean is_rtl;
 
   for (tmp_list = notebook->children; tmp_list; tmp_list = tmp_list->next)
     {
@@ -1516,9 +1520,10 @@ gtk_notebook_get_event_window_position (
     {
       if (rectangle)
 	{
+	  is_rtl = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
 	  rectangle->x = widget->allocation.x + border_width;
 	  rectangle->y = widget->allocation.y + border_width;
-	  
+
 	  switch (tab_pos)
 	    {
 	    case GTK_POS_TOP:
@@ -1527,6 +1532,12 @@ gtk_notebook_get_event_window_position (
 	      rectangle->height = visible_page->requisition.height;
 	      if (tab_pos == GTK_POS_BOTTOM)
 		rectangle->y += widget->allocation.height - 2 * border_width - rectangle->height;
+	      if (priv->action_widget && GTK_WIDGET_VISIBLE (priv->action_widget))
+		{
+		  rectangle->width -= priv->action_widget->allocation.width;
+		  if (is_rtl)
+		    rectangle->x += priv->action_widget->allocation.width;
+		}
 	      break;
 	    case GTK_POS_LEFT:
 	    case GTK_POS_RIGHT:
@@ -1534,6 +1545,8 @@ gtk_notebook_get_event_window_position (
 	      rectangle->height = widget->allocation.height - 2 * border_width;
 	      if (tab_pos == GTK_POS_RIGHT)
 		rectangle->x += widget->allocation.width - 2 * border_width - rectangle->width;
+	      if (priv->action_widget && GTK_WIDGET_VISIBLE (priv->action_widget))
+		rectangle->height -= priv->action_widget->allocation.height;
 	      break;
 	    }
 	}
@@ -1555,6 +1568,7 @@ gtk_notebook_get_event_window_position (
 static void
 gtk_notebook_map (GtkWidget *widget)
 {
+  GtkNotebookPrivate *priv;
   GtkNotebook *notebook;
   GtkNotebookPage *page;
   GList *children;
@@ -1564,12 +1578,18 @@ gtk_notebook_map (GtkWidget *widget)
   GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
 
   notebook = GTK_NOTEBOOK (widget);
+  priv = GTK_NOTEBOOK_GET_PRIVATE (notebook);
 
   if (notebook->cur_page && 
       GTK_WIDGET_VISIBLE (notebook->cur_page->child) &&
       !GTK_WIDGET_MAPPED (notebook->cur_page->child))
     gtk_widget_map (notebook->cur_page->child);
 
+  if (priv->action_widget &&
+      GTK_WIDGET_VISIBLE (priv->action_widget) &&
+      !GTK_WIDGET_MAPPED (priv->action_widget))
+    gtk_widget_map (priv->action_widget);
+
   if (notebook->scrollable)
     gtk_notebook_pages_allocate (notebook);
   else
@@ -1674,10 +1694,12 @@ static void
 gtk_notebook_size_request (GtkWidget      *widget,
 			   GtkRequisition *requisition)
 {
+  GtkNotebookPrivate *priv = GTK_NOTEBOOK_GET_PRIVATE (widget);
   GtkNotebook *notebook = GTK_NOTEBOOK (widget);
   GtkNotebookPage *page;
   GList *children;
   GtkRequisition child_requisition;
+  GtkRequisition action_widget_requisition = { 0, };
   gboolean switch_page = FALSE;
   gint vis_pages;
   gint focus_width;
@@ -1786,6 +1808,13 @@ gtk_notebook_size_request (GtkWidget    
 
 	  if (vis_pages)
 	    {
+	      if (priv->action_widget)
+		{
+		  gtk_widget_size_request (priv->action_widget, &action_widget_requisition);
+		  action_widget_requisition.width += widget->style->xthickness;
+		  action_widget_requisition.height += widget->style->ythickness;
+		}
+
 	      switch (notebook->tab_pos)
 		{
 		case GTK_POS_TOP:
@@ -1797,6 +1826,8 @@ gtk_notebook_size_request (GtkWidget    
 		      widget->requisition.width < tab_width)
 		    tab_height = MAX (tab_height, scroll_arrow_hlength);
 
+		  tab_height = MAX (tab_height, action_widget_requisition.height);
+
 		  padding = 2 * (tab_curvature + focus_width +
 				 notebook->tab_hborder) - tab_overlap;
 		  tab_max += padding;
@@ -1829,6 +1860,7 @@ gtk_notebook_size_request (GtkWidget    
                     widget->requisition.width = MAX (widget->requisition.width,
                                                      tab_width + tab_overlap);
 
+		  widget->requisition.width += action_widget_requisition.width;
 		  widget->requisition.height += tab_height;
 		  break;
 		case GTK_POS_LEFT:
@@ -1841,6 +1873,7 @@ gtk_notebook_size_request (GtkWidget    
 		    tab_width = MAX (tab_width,
                                      arrow_spacing + 2 * scroll_arrow_vlength);
 
+		  tab_width = MAX (tab_width, action_widget_requisition.width);
 		  padding = 2 * (tab_curvature + focus_width +
 				 notebook->tab_vborder) - tab_overlap;
 		  tab_max += padding;
@@ -1853,7 +1886,7 @@ gtk_notebook_size_request (GtkWidget    
 		      if (!GTK_WIDGET_VISIBLE (page->child))
 			continue;
 
-		      page->requisition.width   = tab_width;
+		      page->requisition.width = tab_width;
 
 		      if (notebook->homogeneous)
 			page->requisition.height = tab_max;
@@ -1867,8 +1900,6 @@ gtk_notebook_size_request (GtkWidget    
 		      widget->requisition.height < tab_height)
 		    tab_height = tab_max + (2 * scroll_arrow_vlength + arrow_spacing);
 
-		  widget->requisition.width += tab_width;
-
                   if (notebook->homogeneous && !notebook->scrollable)
                     widget->requisition.height =
 		      MAX (widget->requisition.height,
@@ -1883,6 +1914,9 @@ gtk_notebook_size_request (GtkWidget    
 		  widget->requisition.height = MAX (widget->requisition.height,
 						    vis_pages * tab_max +
 						    tab_overlap);
+
+		  widget->requisition.height += action_widget_requisition.height;
+		  widget->requisition.width += tab_width;
 		  break;
 		}
 	    }
@@ -1939,8 +1973,10 @@ static void
 gtk_notebook_size_allocate (GtkWidget     *widget,
 			    GtkAllocation *allocation)
 {
+  GtkNotebookPrivate *priv = GTK_NOTEBOOK_GET_PRIVATE (widget);
   GtkNotebook *notebook = GTK_NOTEBOOK (widget);
   gint tab_pos = get_effective_tab_pos (notebook);
+  gboolean is_rtl;
 
   widget->allocation = *allocation;
   if (GTK_WIDGET_REALIZED (widget))
@@ -1964,6 +2000,7 @@ gtk_notebook_size_allocate (GtkWidget   
       gint border_width = GTK_CONTAINER (widget)->border_width;
       GtkNotebookPage *page;
       GtkAllocation child_allocation;
+      GtkAllocation action_widget_allocation;
       GList *children;
       
       child_allocation.x = widget->allocation.x + border_width;
@@ -1999,6 +2036,49 @@ gtk_notebook_size_allocate (GtkWidget   
 			 notebook->cur_page->requisition.width);
 		  break;
 		}
+
+	      if (priv->action_widget)
+		{
+		  action_widget_allocation.x = widget->allocation.x + border_width;
+		  action_widget_allocation.y = widget->allocation.y + border_width;
+		  is_rtl = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
+
+		  switch (tab_pos)
+		    {
+		    case GTK_POS_BOTTOM:
+		      action_widget_allocation.y +=
+			widget->allocation.height - 2 * border_width - notebook->cur_page->requisition.height;
+		      /* fall through */
+		    case GTK_POS_TOP:
+		      action_widget_allocation.width = priv->action_widget->requisition.width;
+		      action_widget_allocation.height = notebook->cur_page->requisition.height - widget->style->ythickness;
+
+		      if (!is_rtl)
+			action_widget_allocation.x +=
+			  widget->allocation.width - 2 * border_width -
+			  priv->action_widget->requisition.width;
+
+		      if (tab_pos == GTK_POS_TOP)
+			action_widget_allocation.y += widget->style->ythickness;
+		      break;
+		    case GTK_POS_RIGHT:
+		      action_widget_allocation.x +=
+			widget->allocation.width - 2 * border_width - notebook->cur_page->requisition.width;
+		      /* fall through */
+		    case GTK_POS_LEFT:
+		      action_widget_allocation.height = priv->action_widget->requisition.height;
+		      action_widget_allocation.width = notebook->cur_page->requisition.width - widget->style->xthickness;
+		      action_widget_allocation.y +=
+			widget->allocation.height - 2 * border_width -
+			priv->action_widget->requisition.height;
+
+		      if (tab_pos == GTK_POS_LEFT)
+			action_widget_allocation.x += widget->style->xthickness;
+		      break;
+		    }
+
+		  gtk_widget_size_allocate (priv->action_widget, &action_widget_allocation);
+		}
 	    }
 	}
 
@@ -2069,6 +2149,10 @@ gtk_notebook_expose (GtkWidget      *wid
 	gtk_container_propagate_expose (GTK_CONTAINER (notebook),
 					notebook->cur_page->child,
 					event);
+
+      if (priv->action_widget)
+	gtk_container_propagate_expose (GTK_CONTAINER (notebook),
+					priv->action_widget, event);
     }
 
   return FALSE;
@@ -2298,6 +2382,7 @@ static gboolean
 gtk_notebook_scroll (GtkWidget      *widget,
                      GdkEventScroll *event)
 {
+  GtkNotebookPrivate *priv = GTK_NOTEBOOK_GET_PRIVATE (widget);
   GtkNotebook *notebook = GTK_NOTEBOOK (widget);
 
   GtkWidget* child;
@@ -2312,6 +2397,10 @@ gtk_notebook_scroll (GtkWidget      *wid
   /* ignore scroll events from the content of the page */
   if (!originator || gtk_widget_is_ancestor (originator, child) || originator == child)
     return FALSE;
+
+  /* nor from the action area */
+  if (gtk_widget_is_ancestor (originator, priv->action_widget) || originator == priv->action_widget)
+    return FALSE;
   
   switch (event->direction)
     {
@@ -2737,24 +2826,27 @@ static GtkNotebookPointerPosition
 get_pointer_position (GtkNotebook *notebook)
 {
   GtkWidget *widget = (GtkWidget *) notebook;
-  GtkContainer *container = (GtkContainer *) notebook;
   GtkNotebookPrivate *priv = GTK_NOTEBOOK_GET_PRIVATE (notebook);
+  gint wx, wy, width, height;
   gboolean is_rtl;
 
   if (!notebook->scrollable)
     return POINTER_BETWEEN;
 
+  gdk_window_get_position (notebook->event_window, &wx, &wy);
+  gdk_drawable_get_size (GDK_DRAWABLE (notebook->event_window), &width, &height);
+
   if (notebook->tab_pos == GTK_POS_TOP ||
       notebook->tab_pos == GTK_POS_BOTTOM)
     {
       gint x;
 
       is_rtl = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
-      x = priv->mouse_x - widget->allocation.x;
+      x = priv->mouse_x - wx;
 
-      if (x > widget->allocation.width - 2 * container->border_width - SCROLL_THRESHOLD)
+      if (x > width - SCROLL_THRESHOLD)
 	return (is_rtl) ? POINTER_BEFORE : POINTER_AFTER;
-      else if (x < SCROLL_THRESHOLD + container->border_width)
+      else if (x < SCROLL_THRESHOLD)
 	return (is_rtl) ? POINTER_AFTER : POINTER_BEFORE;
       else
 	return POINTER_BETWEEN;
@@ -2763,10 +2855,10 @@ get_pointer_position (GtkNotebook *noteb
     {
       gint y;
 
-      y = priv->mouse_y - widget->allocation.y;
-      if (y > widget->allocation.height - 2 * container->border_width - SCROLL_THRESHOLD)
+      y = priv->mouse_y - wy;
+      if (y > height - SCROLL_THRESHOLD)
 	return POINTER_AFTER;
-      else if (y < SCROLL_THRESHOLD + container->border_width)
+      else if (y < SCROLL_THRESHOLD)
 	return POINTER_BEFORE;
       else
 	return POINTER_BETWEEN;
@@ -3696,6 +3788,7 @@ static gint
 gtk_notebook_focus (GtkWidget        *widget,
 		    GtkDirectionType  direction)
 {
+  GtkNotebookPrivate *priv;
   GtkWidget *old_focus_child;
   GtkNotebook *notebook;
   GtkDirectionType effective_direction;
@@ -3707,6 +3800,7 @@ gtk_notebook_focus (GtkWidget        *wi
 
   container = GTK_CONTAINER (widget);
   notebook = GTK_NOTEBOOK (container);
+  priv = GTK_NOTEBOOK_GET_PRIVATE (notebook);
 
   if (notebook->focus_out)
     {
@@ -3723,18 +3817,39 @@ gtk_notebook_focus (GtkWidget        *wi
     {
       if (gtk_widget_child_focus (old_focus_child, direction))
         return TRUE;
-      
-      switch (effective_direction)
+
+      if (old_focus_child == priv->action_widget)
 	{
-	case GTK_DIR_TAB_BACKWARD:
-	case GTK_DIR_UP:
-	  /* Focus onto the tabs */
-	  return focus_tabs_in (notebook);
-	case GTK_DIR_DOWN:
-	case GTK_DIR_TAB_FORWARD:
-	case GTK_DIR_LEFT:
-	case GTK_DIR_RIGHT:
-	  return FALSE;
+	  switch (effective_direction)
+	    {
+	    case GTK_DIR_TAB_BACKWARD:
+	    case GTK_DIR_DOWN:
+	      return focus_child_in (notebook, GTK_DIR_TAB_FORWARD);
+	    case GTK_DIR_UP:
+	    case GTK_DIR_TAB_FORWARD:
+	    case GTK_DIR_LEFT:
+	    case GTK_DIR_RIGHT:
+	      return FALSE;
+	    }
+	}
+      else
+	{
+	  switch (effective_direction)
+	    {
+	    case GTK_DIR_TAB_BACKWARD:
+	    case GTK_DIR_UP:
+	      /* Focus onto the tabs */
+	      return focus_tabs_in (notebook);
+	    case GTK_DIR_DOWN:
+	    case GTK_DIR_LEFT:
+	    case GTK_DIR_RIGHT:
+	      return FALSE;
+	    case GTK_DIR_TAB_FORWARD:
+	      if (priv->action_widget && GTK_WIDGET_VISIBLE (priv->action_widget))
+		return gtk_widget_child_focus (priv->action_widget, direction);
+	      else
+		return FALSE;
+	    }
 	}
     }
   else if (widget_is_focus)	/* Focus was on tabs */
@@ -3855,6 +3970,7 @@ gtk_notebook_forall (GtkContainer *conta
 		     GtkCallback   callback,
 		     gpointer      callback_data)
 {
+  GtkNotebookPrivate *priv;
   GtkNotebook *notebook;
   GList *children;
 
@@ -3862,6 +3978,7 @@ gtk_notebook_forall (GtkContainer *conta
   g_return_if_fail (callback != NULL);
 
   notebook = GTK_NOTEBOOK (container);
+  priv = GTK_NOTEBOOK_GET_PRIVATE (notebook);
 
   children = notebook->children;
   while (children)
@@ -3878,6 +3995,9 @@ gtk_notebook_forall (GtkContainer *conta
 	    (* callback) (page->tab_label, callback_data);
 	}
     }
+
+  if (priv->action_widget && include_internals)
+    (* callback) (priv->action_widget, callback_data);
 }
 
 static GType
@@ -4714,10 +4834,12 @@ gtk_notebook_tab_space (GtkNotebook *not
   gint arrow_spacing;
   gint scroll_arrow_hlength;
   gint scroll_arrow_vlength;
+  gboolean is_rtl;
 
   widget = GTK_WIDGET (notebook);
   priv = GTK_NOTEBOOK_GET_PRIVATE (notebook);
   children = notebook->children;
+  is_rtl = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
 
   gtk_widget_style_get (GTK_WIDGET (notebook),
                         "arrow-spacing", &arrow_spacing,
@@ -4732,6 +4854,14 @@ gtk_notebook_tab_space (GtkNotebook *not
       *min = widget->allocation.x + GTK_CONTAINER (notebook)->border_width;
       *max = widget->allocation.x + widget->allocation.width - GTK_CONTAINER (notebook)->border_width;
 
+      if (priv->action_widget)
+	{
+	  if (is_rtl)
+	    *min += priv->action_widget->allocation.width + widget->style->xthickness;
+	  else
+	    *max -= priv->action_widget->allocation.width + widget->style->xthickness;
+	}
+
       while (children)
 	{
           GtkNotebookPage *page;
@@ -4749,6 +4879,9 @@ gtk_notebook_tab_space (GtkNotebook *not
       *min = widget->allocation.y + GTK_CONTAINER (notebook)->border_width;
       *max = widget->allocation.y + widget->allocation.height - GTK_CONTAINER (notebook)->border_width;
 
+      if (priv->action_widget)
+	*max -= priv->action_widget->allocation.height + widget->style->ythickness;
+
       while (children)
 	{
           GtkNotebookPage *page;
@@ -4778,8 +4911,7 @@ gtk_notebook_tab_space (GtkNotebook *not
 	      *show_arrows = TRUE;
 
 	      /* take arrows into account */
-	      *tab_space = widget->allocation.width - tab_overlap -
-		2 * GTK_CONTAINER (notebook)->border_width;
+	      *tab_space = *max - *min - tab_overlap;
 
 	      if (notebook->has_after_previous)
 		{
@@ -4813,8 +4945,7 @@ gtk_notebook_tab_space (GtkNotebook *not
 	      *show_arrows = TRUE;
 
 	      /* take arrows into account */
-	      *tab_space = widget->allocation.height -
-		tab_overlap - 2 * GTK_CONTAINER (notebook)->border_width;
+	      *tab_space = *max - *min - tab_overlap;
 
 	      if (notebook->has_after_previous || notebook->has_after_next)
 		{
@@ -7458,5 +7589,44 @@ gtk_notebook_set_tab_detachable (GtkNote
     }
 }
 
+GtkWidget*
+gtk_notebook_get_action_widget (GtkNotebook *notebook)
+{
+  GtkNotebookPrivate *priv;
+
+  g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), NULL);
+
+  priv = GTK_NOTEBOOK_GET_PRIVATE (notebook);
+  return priv->action_widget;
+}
+
+void
+gtk_notebook_set_action_widget (GtkNotebook *notebook,
+				GtkWidget   *widget)
+{
+  GtkNotebookPrivate *priv;
+
+  g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
+  g_return_if_fail (!widget || GTK_IS_WIDGET (widget));
+  g_return_if_fail (widget->parent == NULL);
+
+  priv = GTK_NOTEBOOK_GET_PRIVATE (notebook);
+
+  if (priv->action_widget)
+    gtk_widget_unparent (priv->action_widget);
+
+  priv->action_widget = widget;
+
+  if (priv->action_widget)
+    {
+      gtk_widget_set_parent (priv->action_widget, GTK_WIDGET (notebook));
+
+      if (GTK_WIDGET_REALIZED (GTK_WIDGET (notebook)))
+	gtk_widget_realize (priv->action_widget);
+    }
+
+  gtk_widget_queue_resize (GTK_WIDGET (notebook));
+}
+
 #define __GTK_NOTEBOOK_C__
 #include "gtkaliasdef.c"
Index: gtk/gtknotebook.h
===================================================================
--- gtk/gtknotebook.h	(revision 17233)
+++ gtk/gtknotebook.h	(working copy)
@@ -268,6 +268,12 @@ void gtk_notebook_set_tab_detachable    
 					   GtkWidget   *child,
 					   gboolean     detachable);
 
+GtkWidget* gtk_notebook_get_action_widget (GtkNotebook *notebook);
+void       gtk_notebook_set_action_widget (GtkNotebook *notebook,
+					   GtkWidget   *widget);
+
+
+
 #ifndef GTK_DISABLE_DEPRECATED
 #define	gtk_notebook_current_page               gtk_notebook_get_current_page
 #define gtk_notebook_set_page                   gtk_notebook_set_current_page
Index: gtk/gtk.symbols
===================================================================
--- gtk/gtk.symbols	(revision 17233)
+++ gtk/gtk.symbols	(working copy)
@@ -2387,6 +2387,8 @@ gtk_notebook_get_tab_reorderable
 gtk_notebook_set_tab_reorderable
 gtk_notebook_get_tab_detachable
 gtk_notebook_set_tab_detachable
+gtk_notebook_get_action_widget
+gtk_notebook_set_action_widget
 #endif
 #endif
 
