]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtknotebook.c
treeview: Don't emit cursor-changed in destruction
[~andy/gtk] / gtk / gtknotebook.c
index 7b44f82655a6255a3ef454d5b329b182335eba51..5f0ce009a8a72123c2ff8dc185c1e7b4c492a163 100644 (file)
@@ -13,9 +13,7 @@
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  */
 
 /*
@@ -43,6 +41,9 @@
 #include "gtkdnd.h"
 #include "gtkbuildable.h"
 #include "gtktypebuiltins.h"
+#include "gtkwidgetpath.h"
+#include "gtkwidgetprivate.h"
+#include "a11y/gtknotebookaccessible.h"
 
 
 /**
@@ -149,9 +150,7 @@ struct _GtkNotebookPrivate
 
   guint          dnd_timer;
   guint          switch_tab_timer;
-
-  guint16        tab_hborder;
-  guint16        tab_vborder;
+  GList         *switch_tab;
 
   guint32        timer;
   guint32        timestamp;
@@ -163,8 +162,6 @@ struct _GtkNotebookPrivate
   guint          during_reorder     : 1;
   guint          focus_out          : 1; /* Flag used by ::move-focus-out implementation */
   guint          has_scrolled       : 1;
-  guint          have_visible_child : 1;
-  guint          homogeneous        : 1;
   guint          in_child           : 3;
   guint          need_timer         : 1;
   guint          show_border        : 1;
@@ -440,6 +437,7 @@ static GtkNotebook *gtk_notebook_create_window (GtkNotebook    *notebook,
 
 /*** GtkNotebook Private Functions ***/
 static void gtk_notebook_redraw_tabs         (GtkNotebook      *notebook);
+static void gtk_notebook_redraw_tabs_junction (GtkNotebook     *notebook);
 static void gtk_notebook_redraw_arrows       (GtkNotebook      *notebook);
 static void gtk_notebook_real_remove         (GtkNotebook      *notebook,
                                               GList            *list);
@@ -464,7 +462,7 @@ static void gtk_notebook_paint               (GtkWidget        *widget,
 static void gtk_notebook_draw_tab            (GtkNotebook      *notebook,
                                               GtkNotebookPage  *page,
                                               cairo_t          *cr,
-                                              GtkRegionFlags    flags);
+                                              gboolean          use_flags);
 static void gtk_notebook_draw_arrow          (GtkNotebook      *notebook,
                                               cairo_t          *cr,
                                               GtkNotebookArrow  arrow);
@@ -1072,7 +1070,7 @@ gtk_notebook_class_init (GtkNotebookClass *class)
    * a notebook where the tab will be attached. It is also
    * responsible for moving/resizing the window and adding the
    * necessary properties to the notebook (e.g. the
-   * #GtkNotebook:group ).
+   * #GtkNotebook:group-name ).
    *
    * Returns: (transfer none): a #GtkNotebook that @page should be
    *     added to, or %NULL.
@@ -1152,6 +1150,8 @@ gtk_notebook_class_init (GtkNotebookClass *class)
   add_tab_bindings (binding_set, GDK_CONTROL_MASK | GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
 
   g_type_class_add_private (class, sizeof (GtkNotebookPrivate));
+
+  gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_NOTEBOOK_ACCESSIBLE);
 }
 
 static void
@@ -1175,9 +1175,6 @@ gtk_notebook_init (GtkNotebook *notebook)
   priv->event_window = NULL;
   priv->menu = NULL;
 
-  priv->tab_hborder = 2;
-  priv->tab_vborder = 2;
-
   priv->show_tabs = TRUE;
   priv->show_border = TRUE;
   priv->tab_pos = GTK_POS_TOP;
@@ -1187,7 +1184,6 @@ gtk_notebook_init (GtkNotebook *notebook)
   priv->button = 0;
   priv->need_timer = 0;
   priv->child_has_focus = FALSE;
-  priv->have_visible_child = FALSE;
   priv->focus_out = FALSE;
 
   priv->has_before_previous = 1;
@@ -1679,12 +1675,36 @@ gtk_notebook_get_property (GObject         *object,
  * gtk_notebook_drag_data_get
  * gtk_notebook_drag_data_received
  */
+static void
+remove_switch_tab_timer (GtkNotebook *notebook)
+{
+  GtkNotebookPrivate *priv = notebook->priv;
+
+  if (priv->switch_tab_timer)
+    {
+      g_source_remove (priv->switch_tab_timer);
+      priv->switch_tab_timer = 0;
+    }
+}
+
 static void
 gtk_notebook_destroy (GtkWidget *widget)
 {
   GtkNotebook *notebook = GTK_NOTEBOOK (widget);
   GtkNotebookPrivate *priv = notebook->priv;
 
+  if (priv->action_widget[GTK_PACK_START])
+    {
+      gtk_widget_unparent (priv->action_widget[GTK_PACK_START]);
+      priv->action_widget[GTK_PACK_START] = NULL;
+    }
+
+  if (priv->action_widget[GTK_PACK_END])
+    {
+      gtk_widget_unparent (priv->action_widget[GTK_PACK_END]);
+      priv->action_widget[GTK_PACK_END] = NULL;
+    }
+
   if (priv->menu)
     gtk_notebook_popup_disable (notebook);
 
@@ -1694,11 +1714,7 @@ gtk_notebook_destroy (GtkWidget *widget)
       priv->source_targets = NULL;
     }
 
-  if (priv->switch_tab_timer)
-    {
-      g_source_remove (priv->switch_tab_timer);
-      priv->switch_tab_timer = 0;
-    }
+  remove_switch_tab_timer (notebook);
 
   GTK_WIDGET_CLASS (gtk_notebook_parent_class)->destroy (widget);
 }
@@ -1892,7 +1908,7 @@ gtk_notebook_realize (GtkWidget *widget)
 
   priv->event_window = gdk_window_new (gtk_widget_get_parent_window (widget),
                                            &attributes, attributes_mask);
-  gdk_window_set_user_data (priv->event_window, notebook);
+  gtk_widget_register_window (widget, priv->event_window);
 }
 
 static void
@@ -1901,13 +1917,13 @@ gtk_notebook_unrealize (GtkWidget *widget)
   GtkNotebook *notebook = GTK_NOTEBOOK (widget);
   GtkNotebookPrivate *priv = notebook->priv;
 
-  gdk_window_set_user_data (priv->event_window, NULL);
+  gtk_widget_unregister_window (widget, priv->event_window);
   gdk_window_destroy (priv->event_window);
   priv->event_window = NULL;
 
   if (priv->drag_window)
     {
-      gdk_window_set_user_data (priv->drag_window, NULL);
+      gtk_widget_unregister_window (widget, priv->drag_window);
       gdk_window_destroy (priv->drag_window);
       priv->drag_window = NULL;
     }
@@ -1960,6 +1976,48 @@ _gtk_notebook_get_tab_flags (GtkNotebook     *notebook,
   return flags;
 }
 
+static GtkStateFlags
+notebook_tab_prepare_style_context (GtkNotebook *notebook,
+                                    GtkNotebookPage *page,
+                                    GtkStyleContext *context,
+                                    gboolean use_flags)
+{
+  gint tab_pos = get_effective_tab_pos (notebook);
+  GtkRegionFlags flags = 0;
+  GtkStateFlags state = gtk_style_context_get_state (context);
+
+  if (page != NULL &&
+      page == notebook->priv->cur_page)
+    state |= GTK_STATE_FLAG_ACTIVE;
+
+  gtk_style_context_set_state (context, state);
+
+  if (use_flags && (page != NULL))
+    flags = _gtk_notebook_get_tab_flags (notebook, page);
+
+  gtk_style_context_add_region (context, GTK_STYLE_REGION_TAB, flags);
+
+  switch (tab_pos)
+    {
+    case GTK_POS_TOP:
+      gtk_style_context_add_class (context, GTK_STYLE_CLASS_TOP);
+      break;
+    case GTK_POS_BOTTOM:
+      gtk_style_context_add_class (context, GTK_STYLE_CLASS_BOTTOM);
+      break;
+    case GTK_POS_LEFT:
+      gtk_style_context_add_class (context, GTK_STYLE_CLASS_LEFT);
+      break;
+    case GTK_POS_RIGHT:
+      gtk_style_context_add_class (context, GTK_STYLE_CLASS_RIGHT);
+      break;
+    default:
+      break;
+    }
+
+  return state;
+}
+
 static void
 gtk_notebook_get_preferred_tabs_size (GtkNotebook    *notebook,
                                       GtkRequisition *requisition)
@@ -1984,6 +2042,7 @@ gtk_notebook_get_preferred_tabs_size (GtkNotebook    *notebook,
   gint tab_overlap;
   gint tab_curvature;
   gint arrow_spacing;
+  gint initial_gap;
   gint scroll_arrow_hlength;
   gint scroll_arrow_vlength;
 
@@ -1993,6 +2052,7 @@ gtk_notebook_get_preferred_tabs_size (GtkNotebook    *notebook,
   gtk_widget_style_get (widget,
                         "focus-line-width", &focus_width,
                         "focus-padding", &focus_pad,
+                        "initial-gap", &initial_gap,
                         "tab-overlap", &tab_overlap,
                         "tab-curvature", &tab_curvature,
                         "arrow-spacing", &arrow_spacing,
@@ -2008,6 +2068,7 @@ gtk_notebook_get_preferred_tabs_size (GtkNotebook    *notebook,
       if (gtk_widget_get_visible (page->child))
         {
           GtkBorder tab_padding;
+          GtkStateFlags state;
 
           vis_pages++;
 
@@ -2019,9 +2080,8 @@ gtk_notebook_get_preferred_tabs_size (GtkNotebook    *notebook,
 
           /* Get border/padding for tab */
           gtk_style_context_save (context);
-          gtk_style_context_add_region (context, GTK_STYLE_REGION_TAB,
-                                        _gtk_notebook_get_tab_flags (notebook, page));
-          gtk_style_context_get_padding (context, 0, &tab_padding);
+          state = notebook_tab_prepare_style_context (notebook, page, context, TRUE);
+          gtk_style_context_get_padding (context, state, &tab_padding);
           gtk_style_context_restore (context);
 
           page->requisition.width = child_requisition.width +
@@ -2034,13 +2094,11 @@ gtk_notebook_get_preferred_tabs_size (GtkNotebook    *notebook,
             {
             case GTK_POS_TOP:
             case GTK_POS_BOTTOM:
-              page->requisition.height += 2 * priv->tab_vborder;
               tab_height = MAX (tab_height, page->requisition.height);
               tab_max = MAX (tab_max, page->requisition.width);
               break;
             case GTK_POS_LEFT:
             case GTK_POS_RIGHT:
-              page->requisition.width += 2 * priv->tab_hborder;
               tab_width = MAX (tab_width, page->requisition.width);
               tab_max = MAX (tab_max, page->requisition.height);
               break;
@@ -2076,7 +2134,7 @@ gtk_notebook_get_preferred_tabs_size (GtkNotebook    *notebook,
           tab_height = MAX (tab_height, action_widget_requisition[ACTION_WIDGET_START].height);
           tab_height = MAX (tab_height, action_widget_requisition[ACTION_WIDGET_END].height);
 
-          padding = 2 * (tab_curvature + priv->tab_hborder) - tab_overlap;
+          padding = 2 * tab_curvature - tab_overlap;
           tab_max += padding;
           while (children)
             {
@@ -2086,10 +2144,7 @@ gtk_notebook_get_preferred_tabs_size (GtkNotebook    *notebook,
               if (!gtk_widget_get_visible (page->child))
                 continue;
 
-              if (priv->homogeneous)
-                page->requisition.width = tab_max;
-              else
-                page->requisition.width += padding;
+              page->requisition.width += padding;
 
               tab_width += page->requisition.width;
               page->requisition.height = tab_height;
@@ -2101,10 +2156,7 @@ gtk_notebook_get_preferred_tabs_size (GtkNotebook    *notebook,
 
           action_width += action_widget_requisition[ACTION_WIDGET_START].width;
           action_width += action_widget_requisition[ACTION_WIDGET_END].width;
-          if (priv->homogeneous && !priv->scrollable)
-            requisition->width = vis_pages * tab_max + tab_overlap + action_width;
-          else
-            requisition->width = tab_width + tab_overlap + action_width;
+          requisition->width = tab_width + tab_overlap + action_width + initial_gap;
 
           requisition->height = tab_height;
           break;
@@ -2119,7 +2171,7 @@ gtk_notebook_get_preferred_tabs_size (GtkNotebook    *notebook,
           tab_width = MAX (tab_width, action_widget_requisition[ACTION_WIDGET_START].width);
           tab_width = MAX (tab_width, action_widget_requisition[ACTION_WIDGET_END].width);
 
-          padding = 2 * (tab_curvature + priv->tab_vborder) - tab_overlap;
+          padding = 2 * tab_curvature - tab_overlap;
           tab_max += padding;
 
           while (children)
@@ -2132,10 +2184,7 @@ gtk_notebook_get_preferred_tabs_size (GtkNotebook    *notebook,
 
               page->requisition.width = tab_width;
 
-              if (priv->homogeneous)
-                page->requisition.height = tab_max;
-              else
-                page->requisition.height += padding;
+              page->requisition.height += padding;
 
               tab_height += page->requisition.height;
             }
@@ -2146,15 +2195,9 @@ gtk_notebook_get_preferred_tabs_size (GtkNotebook    *notebook,
           action_height += action_widget_requisition[ACTION_WIDGET_START].height;
           action_height += action_widget_requisition[ACTION_WIDGET_END].height;
 
-          if (priv->homogeneous && !priv->scrollable)
-            requisition->height = vis_pages * tab_max + tab_overlap + action_height;
-          else
-            requisition->height = tab_height + tab_overlap + action_height;
+          requisition->height = tab_height + tab_overlap + action_height + initial_gap;
 
-          if (!priv->homogeneous || priv->scrollable)
-            vis_pages = 1;
-          requisition->height = MAX (requisition->height,
-                                     vis_pages * tab_max + tab_overlap);
+          requisition->height = MAX (requisition->height, tab_max + tab_overlap);
 
           requisition->width = tab_width;
           break;
@@ -2190,6 +2233,27 @@ get_preferred_size_for_size (GtkWidget      *widget,
       gtk_widget_get_preferred_height_for_width (widget, size, minimum, natural);
 }
 
+static void
+get_padding_and_border (GtkNotebook *notebook,
+                        GtkBorder *border)
+{
+  GtkStyleContext *context;
+
+  context = gtk_widget_get_style_context (GTK_WIDGET (notebook));
+  gtk_style_context_get_padding (context, 0, border);
+
+  if (notebook->priv->show_border || notebook->priv->show_tabs)
+    {
+      GtkBorder tmp;
+
+      gtk_style_context_get_border (context, 0, &tmp);
+      border->top += tmp.top;
+      border->right += tmp.right;
+      border->bottom += tmp.bottom;
+      border->left += tmp.left;
+    }
+}
+
 static void
 gtk_notebook_size_request (GtkWidget      *widget,
                            GtkOrientation  orientation,
@@ -2250,11 +2314,9 @@ gtk_notebook_size_request (GtkWidget      *widget,
 
   if (priv->show_border || priv->show_tabs)
     {
-      GtkStyleContext *context;
       GtkBorder notebook_padding;
 
-      context = gtk_widget_get_style_context (widget);
-      gtk_style_context_get_padding (context, 0, &notebook_padding);
+      get_padding_and_border (notebook, &notebook_padding);
 
       if (orientation == GTK_ORIENTATION_HORIZONTAL)
         {
@@ -2269,7 +2331,7 @@ gtk_notebook_size_request (GtkWidget      *widget,
 
       if (priv->show_tabs)
         {
-          GtkRequisition tabs_requisition;
+          GtkRequisition tabs_requisition = { 0, 0 };
 
           gtk_notebook_get_preferred_tabs_size (notebook, &tabs_requisition);
           if (orientation == GTK_ORIENTATION_HORIZONTAL)
@@ -2427,11 +2489,9 @@ gtk_notebook_size_allocate (GtkWidget     *widget,
 
       if (priv->show_tabs || priv->show_border)
         {
-          GtkStyleContext *context;
           GtkBorder padding;
 
-          context = gtk_widget_get_style_context (widget);
-          gtk_style_context_get_padding (context, 0, &padding);
+          get_padding_and_border (notebook, &padding);
 
           child_allocation.x += padding.left;
           child_allocation.y += padding.top;
@@ -2444,6 +2504,7 @@ gtk_notebook_size_allocate (GtkWidget     *widget,
                 {
                 case GTK_POS_TOP:
                   child_allocation.y += priv->cur_page->requisition.height;
+                  /* fall thru */
                 case GTK_POS_BOTTOM:
                   child_allocation.height =
                     MAX (1, child_allocation.height -
@@ -2451,6 +2512,7 @@ gtk_notebook_size_allocate (GtkWidget     *widget,
                   break;
                 case GTK_POS_LEFT:
                   child_allocation.x += priv->cur_page->requisition.width;
+                  /* fall thru */
                 case GTK_POS_RIGHT:
                   child_allocation.width =
                     MAX (1, child_allocation.width -
@@ -2576,27 +2638,12 @@ gtk_notebook_draw (GtkWidget *widget,
   if (priv->operation == DRAG_OPERATION_REORDER &&
       gtk_cairo_should_draw_window (cr, priv->drag_window))
     {
-      GtkStyleContext *context;
-      GdkRGBA bg_color;
-
       cairo_save (cr);
       gtk_cairo_transform_to_window (cr, widget, priv->drag_window);
-      context = gtk_widget_get_style_context (widget);
-
-      /* FIXME: This is a workaround to make tabs reordering work better
-       * with engines with rounded tabs. If the drag window background
-       * isn't set, the rounded corners would be black.
-       *
-       * Ideally, these corners should be made transparent, Either by using
-       * ARGB visuals or shape windows.
-       */
-      gtk_style_context_get_background_color (context, 0, &bg_color);
-      gdk_cairo_set_source_rgba (cr, &bg_color);
-      cairo_paint (cr);
 
       gtk_notebook_draw_tab (notebook,
                              priv->cur_page,
-                             cr, 0);
+                             cr, FALSE);
 
       cairo_restore (cr);
 
@@ -2773,14 +2820,14 @@ gtk_notebook_arrow_button_press (GtkNotebook      *notebook,
   priv->button = button;
   priv->click_child = arrow;
 
-  if (button == 1)
+  if (button == GDK_BUTTON_PRIMARY)
     {
       gtk_notebook_do_arrow (notebook, arrow);
       gtk_notebook_set_scroll_timer (notebook);
     }
-  else if (button == 2)
+  else if (button == GDK_BUTTON_MIDDLE)
     gtk_notebook_page_select (notebook, TRUE);
-  else if (button == 3)
+  else if (button == GDK_BUTTON_SECONDARY)
     gtk_notebook_switch_focus_tab (notebook,
                                    gtk_notebook_search_page (notebook,
                                                              NULL,
@@ -2873,14 +2920,14 @@ gtk_notebook_button_press (GtkWidget      *widget,
   if (arrow)
     return gtk_notebook_arrow_button_press (notebook, arrow, event->button);
 
-  if (event->button == 3 && priv->menu)
+  if (priv->menu && gdk_event_triggers_context_menu ((GdkEvent *) event))
     {
       gtk_menu_popup (GTK_MENU (priv->menu), NULL, NULL,
                       NULL, NULL, 3, event->time);
       return TRUE;
     }
 
-  if (event->button != 1)
+  if (event->button != GDK_BUTTON_PRIMARY)
     return FALSE;
 
   priv->button = event->button;
@@ -3064,6 +3111,7 @@ show_drag_window (GtkNotebook        *notebook,
     {
       GdkWindowAttr attributes;
       guint attributes_mask;
+      GdkRGBA transparent = {0, 0, 0, 0};
 
       attributes.x = page->allocation.x;
       attributes.y = page->allocation.y;
@@ -3078,7 +3126,8 @@ show_drag_window (GtkNotebook        *notebook,
       priv->drag_window = gdk_window_new (gtk_widget_get_parent_window (widget),
                                           &attributes,
                                           attributes_mask);
-      gdk_window_set_user_data (priv->drag_window, widget);
+      gtk_widget_register_window (widget, priv->drag_window);
+      gdk_window_set_background_rgba (priv->drag_window, &transparent);
     }
 
   g_object_ref (page->tab_label);
@@ -3112,11 +3161,8 @@ hide_drag_window (GtkNotebook        *notebook,
     {
       g_object_ref (page->tab_label);
 
-      if (GTK_IS_WINDOW (parent))
-        {
-          /* parent widget is the drag window */
-          gtk_container_remove (GTK_CONTAINER (parent), page->tab_label);
-        }
+      if (GTK_IS_WINDOW (parent)) /* parent widget is the drag window */
+        gtk_container_remove (GTK_CONTAINER (parent), page->tab_label);
       else
         gtk_widget_unparent (page->tab_label);
 
@@ -3149,7 +3195,7 @@ gtk_notebook_stop_reorder (GtkNotebook *notebook)
     {
       if (priv->during_reorder)
         {
-          gint old_page_num, page_num;
+          gint old_page_num, page_num, i;
           GList *element;
 
           element = get_drop_position (notebook);
@@ -3158,9 +3204,16 @@ gtk_notebook_stop_reorder (GtkNotebook *notebook)
           gtk_notebook_child_reordered (notebook, page);
 
           if (priv->has_scrolled || old_page_num != page_num)
-            g_signal_emit (notebook,
-                           notebook_signals[PAGE_REORDERED], 0,
-                           page->child, page_num);
+           {
+             for (element = priv->children, i = 0; element; element = element->next, i++)
+               {
+                 if (MIN (old_page_num, page_num) <= i && i <= MAX (old_page_num, page_num))
+                   gtk_widget_child_notify (((GtkNotebookPage *) element->data)->child, "position");
+               }
+             g_signal_emit (notebook,
+                            notebook_signals[PAGE_REORDERED], 0,
+                            page->child, page_num);
+           }
 
           priv->has_scrolled = FALSE;
           priv->during_reorder = FALSE;
@@ -3442,6 +3495,8 @@ gtk_notebook_motion_notify (GtkWidget      *widget,
                                   priv->drag_window_y,
                                   page->allocation.width,
                                   page->allocation.height);
+
+          gtk_notebook_redraw_tabs_junction (notebook);
         }
     }
 
@@ -3528,7 +3583,7 @@ on_drag_icon_draw (GtkWidget *widget,
   context = gtk_widget_get_style_context (widget);
 
   gtk_style_context_save (context);
-  gtk_style_context_add_region (context, GTK_STYLE_REGION_TAB, 0);
+  notebook_tab_prepare_style_context (GTK_NOTEBOOK (notebook), NULL, context, FALSE);
 
   gtk_widget_get_preferred_size (widget,
                                  &requisition, NULL);
@@ -3644,20 +3699,20 @@ gtk_notebook_switch_tab_timeout (gpointer data)
 {
   GtkNotebook *notebook = GTK_NOTEBOOK (data);
   GtkNotebookPrivate *priv = notebook->priv;
-  GList *tab;
-  gint x, y;
+  GList *switch_tab;
 
   priv->switch_tab_timer = 0;
-  x = priv->mouse_x;
-  y = priv->mouse_y;
 
-  if ((tab = get_tab_at_pos (notebook, x, y)) != NULL)
+  switch_tab = priv->switch_tab;
+  priv->switch_tab = NULL;
+
+  if (switch_tab)
     {
       /* FIXME: hack, we don't want the
        * focus to move fom the source widget
        */
       priv->child_has_focus = FALSE;
-      gtk_notebook_switch_focus_tab (notebook, tab);
+      gtk_notebook_switch_focus_tab (notebook, switch_tab);
     }
 
   return FALSE;
@@ -3678,6 +3733,8 @@ gtk_notebook_drag_motion (GtkWidget      *widget,
   GtkNotebookArrow arrow;
   guint timeout;
   GdkAtom target, tab_target;
+  GList *tab;
+  gboolean retval = FALSE;
 
   gtk_widget_get_allocation (widget, &allocation);
 
@@ -3689,7 +3746,9 @@ gtk_notebook_drag_motion (GtkWidget      *widget,
       priv->click_child = arrow;
       gtk_notebook_set_scroll_timer (notebook);
       gdk_drag_status (context, 0, time);
-      return TRUE;
+
+      retval = TRUE;
+      goto out;
     }
 
   stop_scrolling (notebook);
@@ -3702,6 +3761,8 @@ gtk_notebook_drag_motion (GtkWidget      *widget,
       GtkNotebook *source;
       GtkWidget *source_child;
 
+      retval = TRUE;
+
       source = GTK_NOTEBOOK (gtk_drag_get_source_widget (context));
       source_child = source->priv->cur_page->child;
 
@@ -3713,7 +3774,7 @@ gtk_notebook_drag_motion (GtkWidget      *widget,
             gtk_widget_is_ancestor (widget, source_child)))
         {
           gdk_drag_status (context, GDK_ACTION_MOVE, time);
-          return TRUE;
+          goto out;
         }
       else
         {
@@ -3728,11 +3789,19 @@ gtk_notebook_drag_motion (GtkWidget      *widget,
 
   if (gtk_notebook_get_event_window_position (notebook, &position) &&
       x >= position.x && x <= position.x + position.width &&
-      y >= position.y && y <= position.y + position.height)
+      y >= position.y && y <= position.y + position.height &&
+      (tab = get_tab_at_pos (notebook, x, y)))
     {
       priv->mouse_x = x;
       priv->mouse_y = y;
 
+      retval = TRUE;
+
+      if (tab != priv->switch_tab)
+        remove_switch_tab_timer (notebook);
+
+      priv->switch_tab = tab;
+
       if (!priv->switch_tab_timer)
         {
           settings = gtk_widget_get_settings (widget);
@@ -3745,14 +3814,11 @@ gtk_notebook_drag_motion (GtkWidget      *widget,
     }
   else
     {
-      if (priv->switch_tab_timer)
-        {
-          g_source_remove (priv->switch_tab_timer);
-          priv->switch_tab_timer = 0;
-        }
+      remove_switch_tab_timer (notebook);
     }
 
-  return (target == tab_target) ? TRUE : FALSE;
+ out:
+  return retval;
 }
 
 static void
@@ -3761,15 +3827,9 @@ gtk_notebook_drag_leave (GtkWidget      *widget,
                          guint           time)
 {
   GtkNotebook *notebook = GTK_NOTEBOOK (widget);
-  GtkNotebookPrivate *priv = notebook->priv;
 
-  if (priv->switch_tab_timer)
-    {
-      g_source_remove (priv->switch_tab_timer);
-      priv->switch_tab_timer = 0;
-    }
-
-  stop_scrolling (GTK_NOTEBOOK (widget));
+  remove_switch_tab_timer (notebook);
+  stop_scrolling (notebook);
 }
 
 static gboolean
@@ -4059,7 +4119,7 @@ gtk_notebook_remove (GtkContainer *container,
   GtkNotebook *notebook = GTK_NOTEBOOK (container);
   GtkNotebookPrivate *priv = notebook->priv;
   GtkNotebookPage *page;
-  GList *children;
+  GList *children, *list;
   gint page_num = 0;
 
   children = priv->children;
@@ -4079,8 +4139,15 @@ gtk_notebook_remove (GtkContainer *container,
 
   g_object_ref (widget);
 
+  list = children->next;
   gtk_notebook_real_remove (notebook, children);
 
+  while (list)
+    {
+      gtk_widget_child_notify (((GtkNotebookPage *)list->data)->child, "position");
+      list = list->next;
+    }
+
   g_signal_emit (notebook,
                  notebook_signals[PAGE_REMOVED],
                  0,
@@ -4098,7 +4165,7 @@ focus_tabs_in (GtkNotebook *notebook)
   if (priv->show_tabs && priv->cur_page)
     {
       gtk_widget_grab_focus (GTK_WIDGET (notebook));
-
+      gtk_notebook_set_focus_child (GTK_CONTAINER (notebook), NULL);
       gtk_notebook_switch_focus_tab (notebook,
                                      g_list_find (priv->children,
                                                   priv->cur_page));
@@ -4528,6 +4595,7 @@ gtk_notebook_real_insert_page (GtkNotebook *notebook,
   GtkNotebookPrivate *priv = notebook->priv;
   GtkNotebookPage *page;
   gint nchildren;
+  GList *list;
 
   gtk_widget_freeze_child_notify (child);
 
@@ -4543,8 +4611,6 @@ gtk_notebook_real_insert_page (GtkNotebook *notebook,
   if (!tab_label)
     {
       page->default_tab = TRUE;
-      if (priv->show_tabs)
-        tab_label = gtk_label_new (NULL);
     }
   page->tab_label = tab_label;
   page->menu_label = menu_label;
@@ -4560,6 +4626,10 @@ gtk_notebook_real_insert_page (GtkNotebook *notebook,
     gtk_notebook_menu_item_create (notebook,
                                    g_list_find (priv->children, page));
 
+  /* child visible will be turned on by switch_page below */
+  if (priv->cur_page != page)
+    gtk_widget_set_child_visible (child, FALSE);
+
   gtk_widget_set_parent (child, GTK_WIDGET (notebook));
   if (tab_label)
     gtk_widget_set_parent (tab_label, GTK_WIDGET (notebook));
@@ -4569,10 +4639,6 @@ gtk_notebook_real_insert_page (GtkNotebook *notebook,
   if (!priv->first_tab)
     priv->first_tab = priv->children;
 
-  /* child visible will be turned on by switch_page below */
-  if (priv->cur_page != page)
-    gtk_widget_set_child_visible (child, FALSE);
-
   if (tab_label)
     {
       if (priv->show_tabs && gtk_widget_get_visible (child))
@@ -4612,7 +4678,14 @@ gtk_notebook_real_insert_page (GtkNotebook *notebook,
   gtk_widget_child_notify (child, "tab-fill");
   gtk_widget_child_notify (child, "tab-label");
   gtk_widget_child_notify (child, "menu-label");
-  gtk_widget_child_notify (child, "position");
+
+  list = g_list_nth (priv->children, position);
+  while (list)
+    {
+      gtk_widget_child_notify (((GtkNotebookPage *)list->data)->child, "position");
+      list = list->next;
+    }
+
   gtk_widget_thaw_child_notify (child);
 
   /* The page-added handler might have reordered the pages, re-get the position */
@@ -4636,7 +4709,6 @@ gtk_notebook_redraw_tabs (GtkNotebook *notebook)
   GtkAllocation allocation;
   GtkWidget *widget;
   GtkNotebookPage *page;
-  GtkStyleContext *context;
   GdkRectangle redraw_rect;
   gint border;
   gint tab_pos = get_effective_tab_pos (notebook);
@@ -4645,48 +4717,108 @@ gtk_notebook_redraw_tabs (GtkNotebook *notebook)
   widget = GTK_WIDGET (notebook);
   border = gtk_container_get_border_width (GTK_CONTAINER (notebook));
 
-  if (!gtk_widget_get_mapped (widget) || !priv->first_tab)
+  if (!gtk_widget_get_mapped (widget) || !priv->cur_page)
     return;
 
-  page = priv->first_tab->data;
+  page = priv->cur_page;
 
   redraw_rect.x = border;
   redraw_rect.y = border;
 
   gtk_widget_get_allocation (widget, &allocation);
 
-  context = gtk_widget_get_style_context (widget);
-  gtk_style_context_get_padding (context, 0, &padding);
+  get_padding_and_border (notebook, &padding);
 
   switch (tab_pos)
     {
     case GTK_POS_BOTTOM:
       redraw_rect.y = allocation.height - border -
         page->allocation.height - padding.bottom;
-
-      if (page != priv->cur_page)
-        redraw_rect.y -= padding.bottom;
       /* fall through */
     case GTK_POS_TOP:
       redraw_rect.width = allocation.width - 2 * border;
       redraw_rect.height = page->allocation.height + padding.top;
 
-      if (page != priv->cur_page)
-        redraw_rect.height += padding.top;
       break;
     case GTK_POS_RIGHT:
       redraw_rect.x = allocation.width - border -
         page->allocation.width - padding.right;
 
-      if (page != priv->cur_page)
-        redraw_rect.x -= padding.right;
       /* fall through */
     case GTK_POS_LEFT:
       redraw_rect.width = page->allocation.width + padding.left;
       redraw_rect.height = allocation.height - 2 * border;
 
-      if (page != priv->cur_page)
-        redraw_rect.width += padding.left;
+      break;
+    }
+
+  redraw_rect.x += allocation.x;
+  redraw_rect.y += allocation.y;
+
+  gdk_window_invalidate_rect (gtk_widget_get_window (widget),
+                              &redraw_rect, TRUE);
+}
+
+static void
+gtk_notebook_redraw_tabs_junction (GtkNotebook *notebook)
+{
+  GtkNotebookPrivate *priv = notebook->priv;
+  GtkAllocation allocation;
+  GtkWidget *widget;
+  GtkNotebookPage *page;
+  GdkRectangle redraw_rect;
+  gint border;
+  gint tab_pos = get_effective_tab_pos (notebook);
+  GtkBorder padding;
+
+  widget = GTK_WIDGET (notebook);
+  border = gtk_container_get_border_width (GTK_CONTAINER (notebook));
+
+  if (!gtk_widget_get_mapped (widget) || !priv->cur_page)
+    return;
+
+  page = priv->cur_page;
+
+  redraw_rect.x = border;
+  redraw_rect.y = border;
+
+  gtk_widget_get_allocation (widget, &allocation);
+
+  get_padding_and_border (notebook, &padding);
+
+  switch (tab_pos)
+    {
+    case GTK_POS_TOP:
+    case GTK_POS_BOTTOM:
+      redraw_rect.width = allocation.width - 2 * border;
+      if (tab_pos == GTK_POS_TOP)
+        {
+          redraw_rect.y = border + page->allocation.y +
+            page->allocation.height;
+          redraw_rect.height = padding.top;
+        }
+      else
+        {
+          redraw_rect.y = allocation.height - border -
+            page->allocation.height - padding.bottom;
+          redraw_rect.height = padding.bottom;
+        }
+      break;
+    case GTK_POS_LEFT:
+    case GTK_POS_RIGHT:
+      redraw_rect.height = allocation.height - 2 * border;
+
+      if (tab_pos == GTK_POS_LEFT)
+        {
+          redraw_rect.x = border + page->allocation.x + page->allocation.width;
+          redraw_rect.width = padding.left;
+        }
+      else
+        {
+          redraw_rect.x = allocation.width - border -
+            page->allocation.width - padding.right;
+          redraw_rect.width = padding.right;
+        }
       break;
     }
 
@@ -4813,7 +4945,23 @@ gtk_notebook_remove_tab_label (GtkNotebook     *notebook,
       page->mnemonic_activate_signal = 0;
 
       gtk_widget_set_state_flags (page->tab_label, 0, TRUE);
-      gtk_widget_unparent (page->tab_label);
+      if (gtk_widget_get_window (page->tab_label) != gtk_widget_get_window (GTK_WIDGET (notebook)) ||
+          !NOTEBOOK_IS_TAB_LABEL_PARENT (notebook, page))
+        {
+          GtkWidget *parent;
+
+          /* we hit this condition during dnd of a detached tab */
+          parent = gtk_widget_get_parent (page->tab_label);
+          if (GTK_IS_WINDOW (parent))
+            gtk_container_remove (GTK_CONTAINER (parent), page->tab_label);
+          else
+            gtk_widget_unparent (page->tab_label);
+        }
+      else
+        {
+          gtk_widget_unparent (page->tab_label);
+        }
+
       page->tab_label = NULL;
     }
 }
@@ -4846,6 +4994,8 @@ gtk_notebook_real_remove (GtkNotebook *notebook,
 
   if (priv->detached_tab == list->data)
     priv->detached_tab = NULL;
+  if (priv->switch_tab == list)
+    priv->switch_tab = NULL;
 
   if (list == priv->first_tab)
     priv->first_tab = next_list;
@@ -5027,7 +5177,6 @@ gtk_notebook_paint (GtkWidget    *widget,
   gboolean is_rtl;
   gint tab_pos;
   GtkStyleContext *context;
-  GtkRegionFlags tab_flags;
 
   notebook = GTK_NOTEBOOK (widget);
   priv = notebook->priv;
@@ -5184,8 +5333,7 @@ gtk_notebook_paint (GtkWidget    *widget,
           !gtk_widget_get_mapped (page->tab_label))
         continue;
 
-      tab_flags = _gtk_notebook_get_tab_flags (notebook, page);
-      gtk_notebook_draw_tab (notebook, page, cr, tab_flags);
+      gtk_notebook_draw_tab (notebook, page, cr, TRUE);
     }
 
   if (children != NULL)
@@ -5209,9 +5357,7 @@ gtk_notebook_paint (GtkWidget    *widget,
       for (children = other_order; children; children = children->next)
         {
           page = children->data;
-
-          tab_flags = _gtk_notebook_get_tab_flags (notebook, page);
-          gtk_notebook_draw_tab (notebook, page, cr, tab_flags);
+          gtk_notebook_draw_tab (notebook, page, cr, TRUE);
         }
 
       g_list_free (other_order);
@@ -5230,20 +5376,16 @@ gtk_notebook_paint (GtkWidget    *widget,
     }
 
   if (priv->operation != DRAG_OPERATION_REORDER)
-    {
-      tab_flags = _gtk_notebook_get_tab_flags (notebook, priv->cur_page);
-      gtk_notebook_draw_tab (notebook, priv->cur_page, cr, tab_flags);
-    }
+    gtk_notebook_draw_tab (notebook, priv->cur_page, cr, TRUE);
 }
 
 static void
 gtk_notebook_draw_tab (GtkNotebook     *notebook,
                        GtkNotebookPage *page,
                        cairo_t         *cr,
-                       GtkRegionFlags   flags)
+                       gboolean         use_flags)
 {
   GtkNotebookPrivate *priv;
-  GtkStateFlags state = 0;
   GtkWidget *widget;
   GtkStyleContext *context;
 
@@ -5255,13 +5397,9 @@ gtk_notebook_draw_tab (GtkNotebook     *notebook,
   widget = GTK_WIDGET (notebook);
   priv = notebook->priv;
 
-  if (priv->cur_page == page)
-    state = GTK_STATE_FLAG_ACTIVE;
-
   context = gtk_widget_get_style_context (widget);
   gtk_style_context_save (context);
-  gtk_style_context_add_region (context, GTK_STYLE_REGION_TAB, flags);
-  gtk_style_context_set_state (context, state);
+  notebook_tab_prepare_style_context (notebook, page, context, use_flags);
 
   gtk_render_extension (context, cr,
                        page->allocation.x,
@@ -5270,7 +5408,7 @@ gtk_notebook_draw_tab (GtkNotebook     *notebook,
                        page->allocation.height,
                        get_tab_gap_pos (notebook));
 
-  if (gtk_widget_has_focus (widget) &&
+  if (gtk_widget_has_visible_focus (widget) &&
       priv->cur_page == page)
     {
       gint focus_width, focus_pad;
@@ -5308,6 +5446,7 @@ gtk_notebook_draw_arrow (GtkNotebook      *notebook,
 
   widget = GTK_WIDGET (notebook);
   context = gtk_widget_get_style_context (widget);
+  state = gtk_widget_get_state_flags (widget);
 
   gtk_notebook_get_arrow_rect (notebook, &arrow_rect, nbarrow);
 
@@ -5320,20 +5459,19 @@ gtk_notebook_draw_arrow (GtkNotebook      *notebook,
                         "scroll-arrow-vlength", &scroll_arrow_vlength,
                         NULL);
 
-  if (priv->in_child == nbarrow)
+  if (priv->focus_tab &&
+      !gtk_notebook_search_page (notebook, priv->focus_tab,
+                                 left ? STEP_PREV : STEP_NEXT, TRUE))
+    {
+      state |= GTK_STATE_FLAG_INSENSITIVE;
+    }
+  else if (priv->in_child == nbarrow)
     {
       state |= GTK_STATE_FLAG_PRELIGHT;
 
       if (priv->click_child == nbarrow)
         state |= GTK_STATE_FLAG_ACTIVE;
     }
-  else
-    state = gtk_widget_get_state_flags (widget);
-
-  if (priv->focus_tab &&
-      !gtk_notebook_search_page (notebook, priv->focus_tab,
-                                 left ? STEP_PREV : STEP_NEXT, TRUE))
-    state = GTK_STATE_FLAG_INSENSITIVE;
 
   if (priv->tab_pos == GTK_POS_LEFT ||
       priv->tab_pos == GTK_POS_RIGHT)
@@ -5376,7 +5514,6 @@ gtk_notebook_tab_space (GtkNotebook *notebook,
   GtkNotebookPrivate *priv = notebook->priv;
   GtkAllocation allocation, action_allocation;
   GtkWidget *widget;
-  GtkStyleContext *context;
   GList *children;
   gint tab_pos = get_effective_tab_pos (notebook);
   gint tab_overlap;
@@ -5393,8 +5530,6 @@ gtk_notebook_tab_space (GtkNotebook *notebook,
   children = priv->children;
   is_rtl = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
 
-  context = gtk_widget_get_style_context (widget);
-
   gtk_widget_style_get (GTK_WIDGET (notebook),
                         "arrow-spacing", &arrow_spacing,
                         "scroll-arrow-hlength", &scroll_arrow_hlength,
@@ -5403,13 +5538,10 @@ gtk_notebook_tab_space (GtkNotebook *notebook,
                         NULL);
 
   border_width = gtk_container_get_border_width (GTK_CONTAINER (notebook));
-  gtk_style_context_get_padding (context, 0, &padding);
+  get_padding_and_border (notebook, &padding);
 
   gtk_widget_get_allocation (widget, &allocation);
 
-  allocation.x += initial_gap;
-  allocation.width -= 2 * initial_gap;
-
   switch (tab_pos)
     {
     case GTK_POS_TOP:
@@ -5475,6 +5607,9 @@ gtk_notebook_tab_space (GtkNotebook *notebook,
       break;
     }
 
+  *min += initial_gap;
+  *max -= (2 * initial_gap);
+
   if (!priv->scrollable)
     *show_arrows = FALSE;
   else
@@ -5746,10 +5881,6 @@ gtk_notebook_calculate_shown_tabs (GtkNotebook  *notebook,
               (gtk_widget_compute_expand (page->tab_label, tab_expand_orientation)))
             (*n)++;
         }
-
-      /* if notebook is homogeneous, all tabs are expanded */
-      if (priv->homogeneous && *n)
-        *n = c;
     }
 }
 
@@ -5803,7 +5934,6 @@ gtk_notebook_calculate_tabs_allocation (GtkNotebook  *notebook,
   gboolean gap_left, packing_changed;
   GtkAllocation child_allocation = { 0, };
   GtkOrientation tab_expand_orientation;
-  GtkBorder padding;
 
   widget = GTK_WIDGET (notebook);
   container = GTK_CONTAINER (notebook);
@@ -5856,16 +5986,10 @@ gtk_notebook_calculate_tabs_allocation (GtkNotebook  *notebook,
   else
     tab_expand_orientation = GTK_ORIENTATION_VERTICAL;
 
-  gtk_style_context_save (context);
-
   while (*children && *children != last_child)
     {
       page = (*children)->data;
 
-      gtk_style_context_add_region (context, GTK_STYLE_REGION_TAB,
-                                    _gtk_notebook_get_tab_flags (notebook, page));
-      gtk_style_context_get_padding (context, 0, &padding);
-
       if (direction == STEP_NEXT)
         *children = gtk_notebook_search_page (notebook, *children, direction, TRUE);
       else
@@ -5878,7 +6002,7 @@ gtk_notebook_calculate_tabs_allocation (GtkNotebook  *notebook,
         continue;
 
       tab_extra_space = 0;
-      if (*expanded_tabs && (showarrow || page->expand || gtk_widget_compute_expand (page->tab_label, tab_expand_orientation) || priv->homogeneous))
+      if (*expanded_tabs && (showarrow || page->expand || gtk_widget_compute_expand (page->tab_label, tab_expand_orientation)))
         {
           tab_extra_space = *remaining_space / *expanded_tabs;
           *remaining_space -= tab_extra_space;
@@ -6000,21 +6124,43 @@ gtk_notebook_calculate_tabs_allocation (GtkNotebook  *notebook,
 
       if (page != priv->cur_page)
         {
+          GtkBorder active_padding, normal_padding, padding;
+
+          /* The active tab is by definition at least the same height as the inactive one.
+           * The padding we're building is the offset between the two tab states, 
+           * so in case the style specifies normal_padding > active_padding we
+           * remove the offset and draw them with the same height.
+           * Note that the padding will still be applied to the tab content though,
+           * see gtk_notebook_page_allocate().
+           */
+          gtk_style_context_save (context);
+          notebook_tab_prepare_style_context (notebook, page, context, TRUE);
+
+          gtk_style_context_get_padding (context, GTK_STATE_FLAG_ACTIVE, &active_padding);
+          gtk_style_context_get_padding (context, GTK_STATE_FLAG_NORMAL, &normal_padding);
+
+          gtk_style_context_restore (context);
+
+          padding.top = MAX (0, active_padding.top - normal_padding.top);
+          padding.right = MAX (0, active_padding.right - normal_padding.right);
+          padding.bottom = MAX (0, active_padding.bottom - normal_padding.bottom);
+          padding.left = MAX (0, active_padding.left - normal_padding.left);
+
           switch (tab_pos)
             {
             case GTK_POS_TOP:
-              page->allocation.y += padding.top;
-              page->allocation.height = MAX (1, page->allocation.height - padding.top);
+              page->allocation.y += padding.top + padding.bottom;
+              page->allocation.height = MAX (1, page->allocation.height - padding.top - padding.bottom);
               break;
             case GTK_POS_BOTTOM:
-              page->allocation.height = MAX (1, page->allocation.height - padding.bottom);
+              page->allocation.height = MAX (1, page->allocation.height - padding.top - padding.bottom);
               break;
             case GTK_POS_LEFT:
-              page->allocation.x += padding.left;
-              page->allocation.width = MAX (1, page->allocation.width - padding.left);
+              page->allocation.x += padding.left + padding.right;
+              page->allocation.width = MAX (1, page->allocation.width - padding.left - padding.right);
               break;
             case GTK_POS_RIGHT:
-              page->allocation.width = MAX (1, page->allocation.width - padding.right);
+              page->allocation.width = MAX (1, page->allocation.width - padding.left - padding.right);
               break;
             }
         }
@@ -6077,8 +6223,6 @@ gtk_notebook_calculate_tabs_allocation (GtkNotebook  *notebook,
         gtk_widget_set_child_visible (page->tab_label, TRUE);
     }
 
-  gtk_style_context_restore (context);
-
   /* Don't move the current tab past the last position during tabs reordering */
   if (children &&
       priv->operation == DRAG_OPERATION_REORDER &&
@@ -6176,6 +6320,7 @@ gtk_notebook_page_allocate (GtkNotebook     *notebook,
   gboolean tab_allocation_changed;
   gboolean was_visible = page->tab_allocated_visible;
   GtkBorder tab_padding;
+  GtkStateFlags state;
 
   if (!page->tab_label ||
       !gtk_widget_get_visible (page->tab_label) ||
@@ -6188,10 +6333,9 @@ gtk_notebook_page_allocate (GtkNotebook     *notebook,
   context = gtk_widget_get_style_context (widget);
 
   gtk_style_context_save (context);
-  gtk_style_context_add_region (context, GTK_STYLE_REGION_TAB,
-                                _gtk_notebook_get_tab_flags (notebook, page));
+  state = notebook_tab_prepare_style_context (notebook, page, context, TRUE);
 
-  gtk_style_context_get_padding (context, 0, &tab_padding);
+  gtk_style_context_get_padding (context, state, &tab_padding);
 
   gtk_widget_get_preferred_size (page->tab_label, &tab_requisition, NULL);
   gtk_widget_style_get (widget,
@@ -6204,7 +6348,7 @@ gtk_notebook_page_allocate (GtkNotebook     *notebook,
     {
     case GTK_POS_TOP:
     case GTK_POS_BOTTOM:
-      padding = tab_curvature + priv->tab_hborder + focus_width + focus_padding;
+      padding = tab_curvature + focus_width + focus_padding;
       if (page->fill)
         {
           child_allocation.x = tab_padding.left + padding;
@@ -6242,18 +6386,16 @@ gtk_notebook_page_allocate (GtkNotebook     *notebook,
           child_allocation.width = tab_requisition.width;
         }
 
-      child_allocation.y = priv->tab_vborder + page->allocation.y;
-
-      if (tab_pos == GTK_POS_TOP)
-        child_allocation.y += tab_padding.top + focus_width + focus_padding;
+      child_allocation.y = 
+        page->allocation.y + tab_padding.top + focus_width + focus_padding;
 
       child_allocation.height = MAX (1, (page->allocation.height -
                                          tab_padding.top - tab_padding.bottom -
-                                         2 * (priv->tab_vborder + focus_width + focus_padding)));
+                                         2 * (focus_width + focus_padding)));
       break;
     case GTK_POS_LEFT:
     case GTK_POS_RIGHT:
-      padding = tab_curvature + priv->tab_vborder + focus_width + focus_padding;
+      padding = tab_curvature + focus_width + focus_padding;
       if (page->fill)
         {
           child_allocation.y = tab_padding.top + padding;
@@ -6291,38 +6433,15 @@ gtk_notebook_page_allocate (GtkNotebook     *notebook,
           child_allocation.height = tab_requisition.height;
         }
 
-      child_allocation.x = priv->tab_hborder + page->allocation.x;
-
-      if (tab_pos == GTK_POS_LEFT)
-        child_allocation.x += tab_padding.left + focus_width + focus_padding;
+      child_allocation.x =
+        page->allocation.x + tab_padding.left + focus_width + focus_padding;
 
       child_allocation.width = MAX (1, (page->allocation.width -
                                          tab_padding.left - tab_padding.right -
-                                         2 * (priv->tab_hborder + focus_width + focus_padding)));
+                                         2 * (focus_width + focus_padding)));
       break;
     }
 
-  if (page != priv->cur_page)
-    {
-      switch (tab_pos)
-        {
-        case GTK_POS_TOP:
-          child_allocation.y -= tab_padding.top;
-          child_allocation.height += tab_padding.top;
-          break;
-        case GTK_POS_BOTTOM:
-          child_allocation.height += tab_padding.bottom;
-          break;
-        case GTK_POS_LEFT:
-          child_allocation.x -= tab_padding.left;
-          child_allocation.width += tab_padding.left;
-          break;
-        case GTK_POS_RIGHT:
-          child_allocation.width += tab_padding.right;
-          break;
-        }
-    }
-
   gtk_widget_get_allocation (page->tab_label, &label_allocation);
   tab_allocation_changed = (child_allocation.x != label_allocation.x ||
                             child_allocation.y != label_allocation.y ||
@@ -6444,11 +6563,6 @@ gtk_notebook_update_tab_states (GtkNotebook *notebook)
         {
           GtkRegionFlags current_flags;
 
-          if (page == priv->cur_page)
-            gtk_widget_set_state_flags (page->tab_label, GTK_STATE_FLAG_ACTIVE, FALSE);
-          else
-            gtk_widget_unset_state_flags (page->tab_label, GTK_STATE_FLAG_ACTIVE);
-
           /* FIXME: We should store these flags somewhere instead of poking
            * the widget's path */
           if (!gtk_widget_path_iter_has_region (gtk_widget_get_path (page->tab_label),
@@ -6456,7 +6570,7 @@ gtk_notebook_update_tab_states (GtkNotebook *notebook)
                                                 GTK_STYLE_REGION_TAB,
                                                 &current_flags)
               || current_flags != _gtk_notebook_get_tab_flags (notebook, page))
-            gtk_widget_reset_style (page->tab_label);
+            _gtk_widget_invalidate_style_context (page->tab_label, GTK_CSS_CHANGE_PARENT_STATE);
         }
     }
 }
@@ -6508,6 +6622,8 @@ gtk_notebook_real_switch_page (GtkNotebook     *notebook,
     }
 
   gtk_notebook_update_tab_states (notebook);
+  gtk_notebook_pages_allocate (notebook);
+
   gtk_widget_queue_resize (GTK_WIDGET (notebook));
   g_object_notify (G_OBJECT (notebook), "page");
 }
@@ -6596,11 +6712,6 @@ gtk_notebook_switch_focus_tab (GtkNotebook *notebook,
     return;
 
   page = priv->focus_tab->data;
-  if (gtk_widget_get_mapped (page->tab_label))
-    gtk_notebook_redraw_tabs (notebook);
-  else
-    gtk_notebook_pages_allocate (notebook);
-
   gtk_notebook_switch_page (notebook, page);
 }
 
@@ -7411,13 +7522,15 @@ gtk_notebook_get_scrollable (GtkNotebook *notebook)
  * Return value: horizontal width of a tab border
  *
  * Since: 2.22
+ *
+ * Deprecated: 3.4: this function returns zero
  */
 guint16
 gtk_notebook_get_tab_hborder (GtkNotebook *notebook)
 {
   g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), FALSE);
 
-  return notebook->priv->tab_hborder;
+  return 0;
 }
 
 /**
@@ -7429,13 +7542,15 @@ gtk_notebook_get_tab_hborder (GtkNotebook *notebook)
  * Return value: vertical width of a tab border
  *
  * Since: 2.22
+ *
+ * Deprecated: 3.4: this function returns zero
  */
 guint16
 gtk_notebook_get_tab_vborder (GtkNotebook *notebook)
 {
   g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), FALSE);
 
-  return notebook->priv->tab_vborder;
+  return 0;
 }
 
 
@@ -7874,7 +7989,7 @@ gtk_notebook_set_tab_label_packing (GtkNotebook *notebook,
   gtk_widget_child_notify (child, "tab-fill");
   gtk_widget_child_notify (child, "position");
   if (priv->show_tabs)
-    gtk_notebook_pages_allocate (notebook);
+    gtk_widget_queue_resize (GTK_WIDGET (notebook));
   gtk_widget_thaw_child_notify (child);
 }
 
@@ -7920,6 +8035,7 @@ gtk_notebook_reorder_child (GtkNotebook *notebook,
   GtkNotebookPage *page;
   gint old_pos;
   gint max_pos;
+  gint i;
 
   g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
   g_return_if_fail (GTK_IS_WIDGET (child));
@@ -7955,7 +8071,12 @@ gtk_notebook_reorder_child (GtkNotebook *notebook,
 
   /* Move around the menu items if necessary */
   gtk_notebook_child_reordered (notebook, page);
-  gtk_widget_child_notify (child, "position");
+
+  for (list = priv->children, i = 0; list; list = list->next, i++)
+    {
+      if (MIN (old_pos, position) <= i && i <= MAX (old_pos, position))
+       gtk_widget_child_notify (((GtkNotebookPage *) list->data)->child, "position");
+    }
 
   if (priv->show_tabs)
     gtk_notebook_pages_allocate (notebook);