aboutsummaryrefslogtreecommitdiffstats
path: root/packages/gtk+/gtk+-2.6.4-1.osso7/gtknotebook.c.diff
diff options
context:
space:
mode:
Diffstat (limited to 'packages/gtk+/gtk+-2.6.4-1.osso7/gtknotebook.c.diff')
-rw-r--r--packages/gtk+/gtk+-2.6.4-1.osso7/gtknotebook.c.diff831
1 files changed, 831 insertions, 0 deletions
diff --git a/packages/gtk+/gtk+-2.6.4-1.osso7/gtknotebook.c.diff b/packages/gtk+/gtk+-2.6.4-1.osso7/gtknotebook.c.diff
index e69de29bb2..4f75106938 100644
--- a/packages/gtk+/gtk+-2.6.4-1.osso7/gtknotebook.c.diff
+++ b/packages/gtk+/gtk+-2.6.4-1.osso7/gtknotebook.c.diff
@@ -0,0 +1,831 @@
+--- gtk+-2.6.4/gtk/gtknotebook.c 2004-09-27 06:43:55.000000000 +0300
++++ gtk+-2.6.4/gtk/gtknotebook.c 2005-04-06 16:19:37.033908352 +0300
+@@ -40,10 +40,10 @@
+
+ #define TAB_OVERLAP 2
+ #define TAB_CURVATURE 1
+-#define ARROW_SIZE 12
++#define ARROW_WIDTH 20
++#define ARROW_HEIGHT 27
+ #define ARROW_SPACING 0
+-#define NOTEBOOK_INIT_SCROLL_DELAY (200)
+-#define NOTEBOOK_SCROLL_DELAY (100)
++#define LABEL_PADDING 0
+
+
+ enum {
+@@ -57,7 +57,9 @@
+
+ enum {
+ STEP_PREV,
+- STEP_NEXT
++ STEP_NEXT,
++ STEP_PREV_CYCLE,
++ STEP_NEXT_CYCLE
+ };
+
+ typedef enum
+@@ -216,7 +218,7 @@
+ GList *list,
+ gboolean destroying);
+ static void gtk_notebook_update_labels (GtkNotebook *notebook);
+-static gint gtk_notebook_timer (GtkNotebook *notebook);
++static gint gtk_notebook_timer (GtkNotebook *notebook );
+ static gint gtk_notebook_page_compare (gconstpointer a,
+ gconstpointer b);
+ static GList* gtk_notebook_find_child (GtkNotebook *notebook,
+@@ -458,7 +460,7 @@
+ g_param_spec_boolean ("scrollable",
+ P_("Scrollable"),
+ P_("If TRUE, scroll arrows are added if there are too many tabs to fit"),
+- FALSE,
++ TRUE,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class,
+ PROP_ENABLE_POPUP,
+@@ -584,6 +586,75 @@
+
+ G_PARAM_READABLE));
+
++ /* Hildon: for adding paddings to the inner borders of the visible page */
++ gtk_widget_class_install_style_property (widget_class,
++ g_param_spec_int ("inner_left_border",
++ _("Inner left border of the visible page"),
++ _("Width of inner left border of the visible page"),
++ 0,
++ G_MAXINT,
++ 0,
++ G_PARAM_READABLE));
++ gtk_widget_class_install_style_property (widget_class,
++ g_param_spec_int ("inner_right_border",
++ _("Inner right border of the visible page"),
++ _("Width of inner right border of the visible page"),
++ 0,
++ G_MAXINT,
++ 0,
++ G_PARAM_READABLE));
++
++ /* Hildon: previously hardcoded constants ARROW_WIDTH, ARROW_HEIGHT,
++ ARROW_SPACING, TAB_OVERLAP and TAB_CURVATURE are now style properties */
++ gtk_widget_class_install_style_property (widget_class,
++ g_param_spec_int ("arrow-width",
++ _("Arrow width"),
++ _("Scroll arrow width"),
++ 0,
++ G_MAXINT,
++ ARROW_WIDTH,
++ G_PARAM_READABLE));
++ gtk_widget_class_install_style_property (widget_class,
++ g_param_spec_int ("arrow-height",
++ _("Arrow height"),
++ _("Scroll arrow height"),
++ 0,
++ G_MAXINT,
++ ARROW_HEIGHT,
++ G_PARAM_READABLE));
++ gtk_widget_class_install_style_property (widget_class,
++ g_param_spec_int ("arrow-spacing",
++ _("Arrow spacing"),
++ _("Scroll arrow spacing"),
++ 0,
++ G_MAXINT,
++ ARROW_SPACING,
++ G_PARAM_READABLE));
++ gtk_widget_class_install_style_property (widget_class,
++ g_param_spec_int ("tab-overlap",
++ _("Tab overlap"),
++ _("Tab overlap"),
++ 0,
++ G_MAXINT,
++ TAB_OVERLAP,
++ G_PARAM_READABLE));
++ gtk_widget_class_install_style_property (widget_class,
++ g_param_spec_int ("tab-curvature",
++ _("Tab curvature"),
++ _("Tab curvature"),
++ 0,
++ G_MAXINT,
++ TAB_CURVATURE,
++ G_PARAM_READABLE));
++ gtk_widget_class_install_style_property (widget_class,
++ g_param_spec_int ("label-padding",
++ _("Label padding"),
++ _("Label padding"),
++ 0,
++ G_MAXINT,
++ LABEL_PADDING,
++ G_PARAM_READABLE));
++
+ notebook_signals[SWITCH_PAGE] =
+ g_signal_new ("switch_page",
+ G_TYPE_FROM_CLASS (gobject_class),
+@@ -705,11 +776,10 @@
+ notebook->show_tabs = TRUE;
+ notebook->show_border = TRUE;
+ notebook->tab_pos = GTK_POS_TOP;
+- notebook->scrollable = FALSE;
++ notebook->scrollable = TRUE;
+ notebook->in_child = 0;
+ notebook->click_child = 0;
+ notebook->button = 0;
+- notebook->need_timer = 0;
+ notebook->child_has_focus = FALSE;
+ notebook->have_visible_child = FALSE;
+ notebook->focus_out = FALSE;
+@@ -1189,9 +1259,18 @@
+ GtkRequisition child_requisition;
+ gboolean switch_page = FALSE;
+ gint vis_pages;
+- gint focus_width;
++ gint focus_width, label_padding;
++ gint arrow_width, arrow_height, arrow_spacing, tab_overlap, tab_curvature;
+
+- gtk_widget_style_get (widget, "focus-line-width", &focus_width, NULL);
++ gtk_widget_style_get (widget,
++ "focus-line-width", &focus_width,
++ "arrow-width", &arrow_width,
++ "arrow-height", &arrow_height,
++ "arrow-spacing", &arrow_spacing,
++ "tab-overlap", &tab_overlap,
++ "tab-curvature", &tab_curvature,
++ "label-padding", &label_padding,
++ NULL);
+
+ widget->requisition.width = 0;
+ widget->requisition.height = 0;
+@@ -1229,6 +1308,22 @@
+ {
+ widget->requisition.width += widget->style->xthickness * 2;
+ widget->requisition.height += widget->style->ythickness * 2;
++
++ /* Hildon kludge: inner border paddings */
++ if (notebook->children && notebook->show_border)
++ {
++ gint inner_left_border, inner_right_border;
++
++ gtk_widget_style_get (widget,
++ "inner_left_border",
++ &inner_left_border,
++ "inner_right_border",
++ &inner_right_border,
++ NULL);
++
++ widget->requisition.width += inner_left_border + inner_right_border;
++ }
++
+
+ if (notebook->show_tabs)
+ {
+@@ -1249,6 +1344,7 @@
+
+ gtk_widget_size_request (page->tab_label,
+ &child_requisition);
++ child_requisition.width += 2 * label_padding;
+
+ page->requisition.width =
+ child_requisition.width +
+@@ -1292,10 +1388,10 @@
+
+ if (notebook->scrollable && vis_pages > 1 &&
+ widget->requisition.width < tab_width)
+- tab_height = MAX (tab_height, ARROW_SIZE);
++ tab_height = MAX (tab_height, arrow_height);
+
+- padding = 2 * (TAB_CURVATURE + focus_width +
+- notebook->tab_hborder) - TAB_OVERLAP;
++ padding = 2 * (tab_curvature + focus_width +
++ notebook->tab_hborder) - tab_overlap;
+ tab_max += padding;
+ while (children)
+ {
+@@ -1316,15 +1412,15 @@
+
+ if (notebook->scrollable && vis_pages > 1 &&
+ widget->requisition.width < tab_width)
+- tab_width = tab_max + 2 * (ARROW_SIZE + ARROW_SPACING);
++ tab_width = tab_max + 2 * (arrow_width + arrow_spacing);
+
+ if (notebook->homogeneous && !notebook->scrollable)
+ widget->requisition.width = MAX (widget->requisition.width,
+ vis_pages * tab_max +
+- TAB_OVERLAP);
++ tab_overlap);
+ else
+ widget->requisition.width = MAX (widget->requisition.width,
+- tab_width + TAB_OVERLAP);
++ tab_width + tab_overlap);
+
+ widget->requisition.height += tab_height;
+ break;
+@@ -1335,10 +1431,10 @@
+
+ if (notebook->scrollable && vis_pages > 1 &&
+ widget->requisition.height < tab_height)
+- tab_width = MAX (tab_width, ARROW_SPACING + 2 * ARROW_SIZE);
++ tab_width = MAX (tab_width, arrow_spacing + 2 * arrow_width);
+
+- padding = 2 * (TAB_CURVATURE + focus_width +
+- notebook->tab_vborder) - TAB_OVERLAP;
++ padding = 2 * (tab_curvature + focus_width +
++ notebook->tab_vborder) - tab_overlap;
+ tab_max += padding;
+
+ while (children)
+@@ -1361,24 +1457,24 @@
+
+ if (notebook->scrollable && vis_pages > 1 &&
+ widget->requisition.height < tab_height)
+- tab_height = tab_max + ARROW_SIZE + ARROW_SPACING;
++ tab_height = tab_max + arrow_height + arrow_spacing;
+
+ widget->requisition.width += tab_width;
+
+ if (notebook->homogeneous && !notebook->scrollable)
+ widget->requisition.height =
+ MAX (widget->requisition.height,
+- vis_pages * tab_max + TAB_OVERLAP);
++ vis_pages * tab_max + tab_overlap);
+ else
+ widget->requisition.height =
+ MAX (widget->requisition.height,
+- tab_height + TAB_OVERLAP);
++ tab_height + tab_overlap);
+
+ if (!notebook->homogeneous || notebook->scrollable)
+ vis_pages = 1;
+ widget->requisition.height = MAX (widget->requisition.height,
+ vis_pages * tab_max +
+- TAB_OVERLAP);
++ tab_overlap);
+ break;
+ }
+ }
+@@ -1499,7 +1595,26 @@
+ }
+ }
+
++ /* Hildon kludge: inner border paddings */
++ if (notebook->show_border)
++ {
++ gint inner_left_border, inner_right_border;
++
++ gtk_widget_style_get (widget,
++ "inner_left_border",
++ &inner_left_border,
++ "inner_right_border",
++ &inner_right_border,
++ NULL);
++
++ child_allocation.x += inner_left_border;
++ child_allocation.width -= inner_left_border + inner_right_border;
++ if (child_allocation.width < 0)
++ child_allocation.width = 0;
++ }
++
+ children = notebook->children;
++
+ while (children)
+ {
+ page = children->data;
+@@ -1580,11 +1695,18 @@
+ GdkRectangle event_window_pos;
+ gboolean before = ARROW_IS_BEFORE (arrow);
+ gboolean left = ARROW_IS_LEFT (arrow);
++ gint arrow_width, arrow_height, arrow_spacing;
++
++ gtk_widget_style_get (GTK_WIDGET(notebook),
++ "arrow-width", &arrow_width,
++ "arrow-height", &arrow_height,
++ "arrow-spacing", &arrow_spacing,
++ NULL);
+
+ if (gtk_notebook_get_event_window_position (notebook, &event_window_pos))
+ {
+- rectangle->width = ARROW_SIZE;
+- rectangle->height = ARROW_SIZE;
++ rectangle->width = arrow_width;
++ rectangle->height = arrow_height;
+
+ switch (notebook->tab_pos)
+ {
+@@ -1602,6 +1724,8 @@
+ rectangle->y += event_window_pos.height - rectangle->height;
+ break;
+ case GTK_POS_TOP:
++ arrow_spacing = - arrow_spacing;
++ /* Fall through */
+ case GTK_POS_BOTTOM:
+ if (before)
+ {
+@@ -1617,7 +1741,11 @@
+ else
+ rectangle->x = event_window_pos.x + event_window_pos.width - 2 * rectangle->width;
+ }
+- rectangle->y = event_window_pos.y + (event_window_pos.height - rectangle->height) / 2;
++ rectangle->y = event_window_pos.y;
++ if (arrow_spacing > 0)
++ rectangle->y += arrow_spacing;
++ else
++ rectangle->y += (event_window_pos.height - rectangle->height) / 2;
+ break;
+ }
+ }
+@@ -1696,6 +1824,10 @@
+ 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);
++ GtkSettings *settings = gtk_settings_get_default ();
++ guint timeout;
++
++ g_object_get (settings, "gtk-initial-timeout", &timeout, NULL);
+
+ if (!GTK_WIDGET_HAS_FOCUS (widget))
+ gtk_widget_grab_focus (widget);
+@@ -1706,14 +1838,14 @@
+ if (event->button == 1)
+ {
+ gtk_notebook_do_arrow (notebook, arrow);
+-
++
+ if (!notebook->timer)
+- {
+- notebook->timer = g_timeout_add (NOTEBOOK_INIT_SCROLL_DELAY,
+- (GSourceFunc) gtk_notebook_timer,
+- (gpointer) notebook);
+- notebook->need_timer = TRUE;
+- }
++ {
++ notebook->timer = g_timeout_add (timeout,
++ (GSourceFunc) gtk_notebook_timer,
++ (gpointer) notebook);
++ notebook->need_timer = TRUE;
++ }
+ }
+ else if (event->button == 2)
+ gtk_notebook_page_select (notebook, TRUE);
+@@ -1862,7 +1994,7 @@
+ static void
+ stop_scrolling (GtkNotebook *notebook)
+ {
+- if (notebook->timer)
++ if (notebook->timer)
+ {
+ g_source_remove (notebook->timer);
+ notebook->timer = 0;
+@@ -2343,9 +2475,9 @@
+ */
+ return focus_child_in (notebook, GTK_DIR_TAB_FORWARD);
+ case GTK_DIR_LEFT:
+- return focus_tabs_move (notebook, direction, STEP_PREV);
++ return focus_tabs_move (notebook, direction, STEP_PREV_CYCLE);
+ case GTK_DIR_RIGHT:
+- return focus_tabs_move (notebook, direction, STEP_NEXT);
++ return focus_tabs_move (notebook, direction, STEP_NEXT_CYCLE);
+ }
+ }
+ else /* Focus was not on widget */
+@@ -2481,7 +2613,6 @@
+ * gtk_notebook_redraw_tabs
+ * gtk_notebook_real_remove
+ * gtk_notebook_update_labels
+- * gtk_notebook_timer
+ * gtk_notebook_page_compare
+ * gtk_notebook_real_page_position
+ * gtk_notebook_search_page
+@@ -2574,22 +2705,27 @@
+ gtk_notebook_timer (GtkNotebook *notebook)
+ {
+ gboolean retval = FALSE;
++ guint timeout;
++ GtkSettings *settings;
+
+ GDK_THREADS_ENTER ();
+
++ settings = gtk_settings_get_default ();
++ g_object_get (settings, "gtk-update-timeout", &timeout, NULL);
++
+ if (notebook->timer)
+ {
+ gtk_notebook_do_arrow (notebook, notebook->click_child);
+
+- if (notebook->need_timer)
+- {
+- notebook->need_timer = FALSE;
+- notebook->timer = g_timeout_add (NOTEBOOK_SCROLL_DELAY,
+- (GSourceFunc) gtk_notebook_timer,
+- (gpointer) notebook);
+- }
++ if (notebook->need_timer)
++ {
++ notebook->need_timer = FALSE;
++ notebook->timer = g_timeout_add (timeout,
++ (GSourceFunc) gtk_notebook_timer,
++ (gpointer) notebook);
++ }
+ else
+- retval = TRUE;
++ retval = TRUE;
+ }
+
+ GDK_THREADS_LEAVE ();
+@@ -2781,10 +2917,12 @@
+ switch (direction)
+ {
+ case STEP_PREV:
++ case STEP_PREV_CYCLE:
+ flag = GTK_PACK_END;
+ break;
+
+ case STEP_NEXT:
++ case STEP_NEXT_CYCLE:
+ flag = GTK_PACK_START;
+ break;
+ }
+@@ -2827,6 +2965,37 @@
+ old_list = list;
+ list = list->prev;
+ }
++
++ /* Hildon hack: keyboard navigation should cycle around */
++ if (direction == STEP_PREV_CYCLE)
++ {
++ /* find and return the last (visible) page */
++ list = g_list_last (notebook->children);
++ if (!find_visible)
++ return list;
++ while (list)
++ {
++ page = list->data;
++ if (GTK_WIDGET_VISIBLE (page->child))
++ return list;
++ list = list->prev;
++ }
++ }
++ if (direction == STEP_NEXT_CYCLE)
++ {
++ /* find and return the first (visible) page */
++ list = g_list_first (notebook->children);
++ if (!find_visible)
++ return list;
++ while (list)
++ {
++ page = list->data;
++ if (GTK_WIDGET_VISIBLE (page->child))
++ return list;
++ list = list->next;
++ }
++ }
++
+ return NULL;
+ }
+
+@@ -2850,6 +3019,7 @@
+ gint gap_x = 0, gap_width = 0, step = STEP_PREV;
+ gboolean is_rtl;
+ gint tab_pos;
++ gboolean paint_box_gap = FALSE;
+
+ g_return_if_fail (GTK_IS_NOTEBOOK (widget));
+ g_return_if_fail (area != NULL);
+@@ -2933,15 +3103,37 @@
+ 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,
+- tab_pos, gap_x, gap_width);
++
++ /* hildon hack to postpone painting until it
++ is known if scroll arrows will be drawn */
++ paint_box_gap = TRUE;
+ }
+
++ /* first, figure out if arrows should be drawn */
+ showarrow = FALSE;
+ children = gtk_notebook_search_page (notebook, NULL, step, TRUE);
++ while (children && !showarrow)
++ {
++ page = children->data;
++ children = gtk_notebook_search_page (notebook, children,
++ step, TRUE);
++ if (!GTK_WIDGET_MAPPED (page->tab_label))
++ showarrow = TRUE;
++ }
++
++ /* then draw content area frame */
++ if (paint_box_gap)
++ gtk_paint_box_gap (widget->style, widget->window,
++ GTK_STATE_NORMAL, GTK_SHADOW_OUT,
++ area, widget,
++ (showarrow && notebook->scrollable)
++ ? "notebook_show_arrow"
++ : "notebook",
++ x, y, width, height,
++ tab_pos, gap_x, gap_width);
++
++ /* and finally draw tabs */
++ children = gtk_notebook_search_page (notebook, NULL, step, TRUE);
+ while (children)
+ {
+ page = children->data;
+@@ -3069,10 +3261,15 @@
+ GdkRectangle arrow_rect;
+ GtkArrowType arrow;
+ gboolean is_rtl, left;
++ gint arrow_width, arrow_height;
+
+ gtk_notebook_get_arrow_rect (notebook, &arrow_rect, nbarrow);
+
+ widget = GTK_WIDGET (notebook);
++ gtk_widget_style_get (widget,
++ "arrow-width", &arrow_width,
++ "arrow-height", &arrow_height,
++ NULL);
+
+ is_rtl = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
+ left = (ARROW_IS_LEFT (nbarrow) && !is_rtl) ||
+@@ -3112,7 +3309,7 @@
+ gtk_paint_arrow (widget->style, widget->window, state_type,
+ shadow_type, NULL, widget, "notebook",
+ arrow, TRUE, arrow_rect.x, arrow_rect.y,
+- ARROW_SIZE, ARROW_SIZE);
++ arrow_width, arrow_height);
+ }
+ }
+
+@@ -3143,13 +3340,25 @@
+ 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;
++ gboolean truncate = FALSE;
++ gint arrow_width, arrow_height, arrow_spacing, tab_overlap;
++ gint total_width, ideal_tab_width, n_expanding_tabs;
+
+ if (!notebook->show_tabs || !notebook->children || !notebook->cur_page)
+ return;
+
++ gtk_widget_style_get (widget,
++ "arrow-width", &arrow_width,
++ "arrow-height", &arrow_height,
++ "arrow-spacing", &arrow_spacing,
++ "tab-overlap", &tab_overlap,
++ NULL);
++
+ child_allocation.x = widget->allocation.x + container->border_width;
+ child_allocation.y = widget->allocation.y + container->border_width;
+
++ total_width = allocation->width - 2 * container->border_width - tab_overlap;
++
+ switch (tab_pos)
+ {
+ case GTK_POS_BOTTOM:
+@@ -3198,27 +3407,26 @@
+ if (GTK_WIDGET_VISIBLE (page->child))
+ tab_space += page->requisition.width;
+ }
+- if (tab_space >
+- allocation->width - 2 * container->border_width - TAB_OVERLAP)
++ if (tab_space > total_width)
+ {
+ showarrow = TRUE;
+ page = focus_tab->data;
+
+- tab_space = allocation->width - TAB_OVERLAP -
++ tab_space = allocation->width - tab_overlap -
+ page->requisition.width - 2 * container->border_width;
+ if (notebook->has_after_previous)
+- tab_space -= ARROW_SPACING + ARROW_SIZE;
++ tab_space -= arrow_spacing + arrow_width;
+ if (notebook->has_after_next)
+- tab_space -= ARROW_SPACING + ARROW_SIZE;
++ tab_space -= arrow_spacing + arrow_width;
+ if (notebook->has_before_previous)
+ {
+- tab_space -= ARROW_SPACING + ARROW_SIZE;
+- child_allocation.x += ARROW_SPACING + ARROW_SIZE;
++ tab_space -= arrow_spacing + arrow_width;
++ child_allocation.x += arrow_spacing + arrow_width;
+ }
+ if (notebook->has_before_next)
+ {
+- tab_space -= ARROW_SPACING + ARROW_SIZE;
+- child_allocation.x += ARROW_SPACING + ARROW_SIZE;
++ tab_space -= arrow_spacing + arrow_width;
++ child_allocation.x += arrow_spacing + arrow_width;
+ }
+ }
+ break;
+@@ -3233,19 +3441,19 @@
+ tab_space += page->requisition.height;
+ }
+ if (tab_space >
+- (allocation->height - 2 * container->border_width - TAB_OVERLAP))
++ (allocation->height - 2 * container->border_width - tab_overlap))
+ {
+ showarrow = TRUE;
+ page = focus_tab->data;
+ tab_space = allocation->height
+- - TAB_OVERLAP - 2 * container->border_width
++ - tab_overlap - 2 * container->border_width
+ - page->requisition.height;
+ if (notebook->has_after_previous || notebook->has_after_next)
+- tab_space -= ARROW_SPACING + ARROW_SIZE;
++ tab_space -= arrow_spacing + arrow_height;
+ if (notebook->has_before_previous || notebook->has_before_next)
+ {
+- tab_space -= ARROW_SPACING + ARROW_SIZE;
+- child_allocation.y += ARROW_SPACING + ARROW_SIZE;
++ tab_space -= arrow_spacing + arrow_height;
++ child_allocation.y += arrow_spacing + arrow_height;
+ }
+ }
+ break;
+@@ -3257,6 +3465,10 @@
+ notebook->first_tab = focus_tab;
+ last_child = gtk_notebook_search_page (notebook, focus_tab,
+ STEP_NEXT, TRUE);
++
++ /* Hildon: there is only one visible tab label
++ and it doesn't fit unless it is truncated */
++ truncate = TRUE;
+ }
+ else
+ {
+@@ -3413,7 +3625,7 @@
+ }
+ tab_space -= allocation->height;
+ }
+- tab_space += 2 * container->border_width + TAB_OVERLAP;
++ tab_space += 2 * container->border_width + tab_overlap;
+ tab_space *= -1;
+ notebook->first_tab = gtk_notebook_search_page (notebook, NULL,
+ STEP_NEXT, TRUE);
+@@ -3432,12 +3644,29 @@
+ if (showarrow)
+ {
+ if (notebook->has_after_previous)
+- child_allocation.x -= ARROW_SPACING + ARROW_SIZE;
++ child_allocation.x -= arrow_spacing + arrow_width;
+ if (notebook->has_after_next)
+- child_allocation.x -= ARROW_SPACING + ARROW_SIZE;
++ child_allocation.x -= arrow_spacing + arrow_width;
+ }
+ }
+
++ ideal_tab_width = (total_width / n);
++ n_expanding_tabs = 0;
++
++ while (children)
++ {
++ if (children == last_child)
++ break;
++
++ page = children->data;
++ children = gtk_notebook_search_page (notebook, children, STEP_NEXT,TRUE);
++
++ if (page->requisition.width <= ideal_tab_width)
++ n_expanding_tabs++;
++ }
++
++ children = notebook->first_tab;
++
+ while (children)
+ {
+ if (children == last_child)
+@@ -3452,9 +3681,11 @@
+ children = gtk_notebook_search_page (notebook, children, STEP_NEXT,TRUE);
+
+ delta = 0;
+- if (n && (showarrow || page->expand || notebook->homogeneous))
++
++ if (n && (showarrow || page->expand || notebook->homogeneous) &&
++ (page->requisition.width <= ideal_tab_width))
+ {
+- new_fill = (tab_space * i++) / n;
++ new_fill = (tab_space * i++) / n_expanding_tabs;
+ delta = new_fill - old_fill;
+ old_fill = new_fill;
+ }
+@@ -3463,15 +3694,18 @@
+ {
+ case GTK_POS_TOP:
+ case GTK_POS_BOTTOM:
++ if (truncate)
++ delta *= -1;
++
+ child_allocation.width = (page->requisition.width +
+- TAB_OVERLAP + delta);
++ tab_overlap + delta);
+ if (is_rtl)
+ child_allocation.x -= child_allocation.width;
+ break;
+ case GTK_POS_LEFT:
+ case GTK_POS_RIGHT:
+ child_allocation.height = (page->requisition.height +
+- TAB_OVERLAP + delta);
++ tab_overlap + delta);
+ break;
+ }
+
+@@ -3482,13 +3716,13 @@
+ case GTK_POS_TOP:
+ case GTK_POS_BOTTOM:
+ if (!is_rtl)
+- child_allocation.x += child_allocation.width - TAB_OVERLAP;
++ child_allocation.x += child_allocation.width - tab_overlap;
+ else
+- child_allocation.x += TAB_OVERLAP;
++ child_allocation.x += tab_overlap;
+ break;
+ case GTK_POS_LEFT:
+ case GTK_POS_RIGHT:
+- child_allocation.y += child_allocation.height - TAB_OVERLAP;
++ child_allocation.y += child_allocation.height - tab_overlap;
+ break;
+ }
+
+@@ -3538,14 +3772,14 @@
+ case GTK_POS_TOP:
+ case GTK_POS_BOTTOM:
+ child_allocation.width = (page->requisition.width +
+- TAB_OVERLAP + delta);
++ tab_overlap + delta);
+ if (!is_rtl)
+ child_allocation.x -= child_allocation.width;
+ break;
+ case GTK_POS_LEFT:
+ case GTK_POS_RIGHT:
+ child_allocation.height = (page->requisition.height +
+- TAB_OVERLAP + delta);
++ tab_overlap + delta);
+ child_allocation.y -= child_allocation.height;
+ break;
+ }
+@@ -3557,13 +3791,13 @@
+ case GTK_POS_TOP:
+ case GTK_POS_BOTTOM:
+ if (!is_rtl)
+- child_allocation.x += TAB_OVERLAP;
++ child_allocation.x += tab_overlap;
+ else
+- child_allocation.x += child_allocation.width - TAB_OVERLAP;
++ child_allocation.x += child_allocation.width - tab_overlap;
+ break;
+ case GTK_POS_LEFT:
+ case GTK_POS_RIGHT:
+- child_allocation.y += TAB_OVERLAP;
++ child_allocation.y += tab_overlap;
+ break;
+ }
+
+@@ -3589,8 +3823,12 @@
+ gint padding;
+ gint focus_width;
+ gint tab_pos = get_effective_tab_pos (notebook);
++ gint tab_curvature;
+
+- gtk_widget_style_get (widget, "focus-line-width", &focus_width, NULL);
++ gtk_widget_style_get (widget,
++ "focus-line-width", &focus_width,
++ "tab-curvature", &tab_curvature,
++ NULL);
+
+ xthickness = widget->style->xthickness;
+ ythickness = widget->style->ythickness;
+@@ -3621,7 +3859,7 @@
+ {
+ case GTK_POS_TOP:
+ case GTK_POS_BOTTOM:
+- padding = TAB_CURVATURE + focus_width + notebook->tab_hborder;
++ padding = tab_curvature + focus_width + notebook->tab_hborder;
+ if (page->fill)
+ {
+ child_allocation.x = (xthickness + focus_width +
+@@ -3646,7 +3884,7 @@
+ break;
+ case GTK_POS_LEFT:
+ case GTK_POS_RIGHT:
+- padding = TAB_CURVATURE + focus_width + notebook->tab_vborder;
++ padding = tab_curvature + focus_width + notebook->tab_vborder;
+ if (page->fill)
+ {
+ child_allocation.y = ythickness + padding;
+@@ -4340,7 +4578,7 @@
+ }
+ page->tab_label = tab_label;
+ page->menu_label = menu_label;
+- page->expand = FALSE;
++ page->expand = TRUE;
+ page->fill = TRUE;
+ page->pack = GTK_PACK_START;
+
+@@ -5046,6 +5284,7 @@
+ {
+ page->default_tab = FALSE;
+ page->tab_label = tab_label;
++
+ gtk_widget_set_parent (page->tab_label, GTK_WIDGET (notebook));
+ }
+ else