]> pilppa.org Git - familiar-h63xx-build.git/blob - org.handhelds.familiar/packages/gtk+/gtk+-2.6.4-1.osso7/gtknotebook.c.diff
OE tree imported from monotone branch org.openembedded.oz354fam083 at revision 8b12e3...
[familiar-h63xx-build.git] / org.handhelds.familiar / packages / gtk+ / gtk+-2.6.4-1.osso7 / gtknotebook.c.diff
1 --- gtk+-2.6.4/gtk/gtknotebook.c        2004-09-27 06:43:55.000000000 +0300
2 +++ gtk+-2.6.4/gtk/gtknotebook.c        2005-04-06 16:19:37.033908352 +0300
3 @@ -40,10 +40,10 @@
4  
5  #define TAB_OVERLAP    2
6  #define TAB_CURVATURE  1
7 -#define ARROW_SIZE     12
8 +#define ARROW_WIDTH    20
9 +#define ARROW_HEIGHT   27
10  #define ARROW_SPACING  0
11 -#define NOTEBOOK_INIT_SCROLL_DELAY (200)
12 -#define NOTEBOOK_SCROLL_DELAY      (100)
13 +#define LABEL_PADDING  0
14  
15  
16  enum {
17 @@ -57,7 +57,9 @@
18  
19  enum {
20    STEP_PREV,
21 -  STEP_NEXT
22 +  STEP_NEXT,
23 +  STEP_PREV_CYCLE,
24 +  STEP_NEXT_CYCLE
25  };
26  
27  typedef enum
28 @@ -216,7 +218,7 @@
29                                               GList            *list,
30                                               gboolean          destroying);
31  static void gtk_notebook_update_labels       (GtkNotebook      *notebook);
32 -static gint gtk_notebook_timer               (GtkNotebook      *notebook);
33 +static gint gtk_notebook_timer               (GtkNotebook      *notebook        );
34  static gint gtk_notebook_page_compare        (gconstpointer     a,
35                                               gconstpointer     b);
36  static GList* gtk_notebook_find_child        (GtkNotebook      *notebook,
37 @@ -458,7 +460,7 @@
38                                    g_param_spec_boolean ("scrollable",
39                                                          P_("Scrollable"),
40                                                          P_("If TRUE, scroll arrows are added if there are too many tabs to fit"),
41 -                                                        FALSE,
42 +                                                        TRUE,
43                                                          G_PARAM_READWRITE));
44    g_object_class_install_property (gobject_class,
45                                    PROP_ENABLE_POPUP,
46 @@ -584,6 +586,75 @@
47                                                                  
48                                                                     G_PARAM_READABLE));
49  
50 +  /* Hildon: for adding paddings to the inner borders of the visible page */
51 +  gtk_widget_class_install_style_property (widget_class,
52 +                                           g_param_spec_int ("inner_left_border",
53 +                                                             _("Inner left border of the visible page"),
54 +                                                             _("Width of inner left border of the visible page"),
55 +                                                             0,
56 +                                                             G_MAXINT,
57 +                                                             0,
58 +                                                             G_PARAM_READABLE));
59 +  gtk_widget_class_install_style_property (widget_class,
60 +                                           g_param_spec_int ("inner_right_border",
61 +                                                             _("Inner right border of the visible page"),
62 +                                                             _("Width of inner right border of the visible page"),
63 +                                                             0,
64 +                                                             G_MAXINT,
65 +                                                             0,
66 +                                                             G_PARAM_READABLE));
67 +
68 +  /* Hildon: previously hardcoded constants ARROW_WIDTH, ARROW_HEIGHT,
69 +     ARROW_SPACING, TAB_OVERLAP and TAB_CURVATURE are now style properties */
70 +  gtk_widget_class_install_style_property (widget_class,
71 +                                           g_param_spec_int ("arrow-width",
72 +                                                             _("Arrow width"),
73 +                                                             _("Scroll arrow width"),
74 +                                                             0,
75 +                                                             G_MAXINT,
76 +                                                             ARROW_WIDTH,
77 +                                                             G_PARAM_READABLE));
78 +  gtk_widget_class_install_style_property (widget_class,
79 +                                           g_param_spec_int ("arrow-height",
80 +                                                             _("Arrow height"),
81 +                                                             _("Scroll arrow height"),
82 +                                                             0,
83 +                                                             G_MAXINT,
84 +                                                             ARROW_HEIGHT,
85 +                                                             G_PARAM_READABLE));
86 +  gtk_widget_class_install_style_property (widget_class,
87 +                                           g_param_spec_int ("arrow-spacing",
88 +                                                             _("Arrow spacing"),
89 +                                                             _("Scroll arrow spacing"),
90 +                                                             0,
91 +                                                             G_MAXINT,
92 +                                                             ARROW_SPACING,
93 +                                                             G_PARAM_READABLE));
94 +  gtk_widget_class_install_style_property (widget_class,
95 +                                           g_param_spec_int ("tab-overlap",
96 +                                                             _("Tab overlap"),
97 +                                                             _("Tab overlap"),
98 +                                                             0,
99 +                                                             G_MAXINT,
100 +                                                             TAB_OVERLAP,
101 +                                                             G_PARAM_READABLE));
102 +  gtk_widget_class_install_style_property (widget_class,
103 +                                           g_param_spec_int ("tab-curvature",
104 +                                                             _("Tab curvature"),
105 +                                                             _("Tab curvature"),
106 +                                                             0,
107 +                                                             G_MAXINT,
108 +                                                             TAB_CURVATURE,
109 +                                                             G_PARAM_READABLE));
110 +  gtk_widget_class_install_style_property (widget_class,
111 +                                           g_param_spec_int ("label-padding",
112 +                                                             _("Label padding"),
113 +                                                             _("Label padding"),
114 +                                                             0,
115 +                                                             G_MAXINT,
116 +                                                             LABEL_PADDING,
117 +                                                             G_PARAM_READABLE));
118 +
119    notebook_signals[SWITCH_PAGE] =
120      g_signal_new ("switch_page",
121                   G_TYPE_FROM_CLASS (gobject_class),
122 @@ -705,11 +776,10 @@
123    notebook->show_tabs = TRUE;
124    notebook->show_border = TRUE;
125    notebook->tab_pos = GTK_POS_TOP;
126 -  notebook->scrollable = FALSE;
127 +  notebook->scrollable = TRUE;
128    notebook->in_child = 0;
129    notebook->click_child = 0;
130    notebook->button = 0;
131 -  notebook->need_timer = 0;
132    notebook->child_has_focus = FALSE;
133    notebook->have_visible_child = FALSE;
134    notebook->focus_out = FALSE;
135 @@ -1189,9 +1259,18 @@
136    GtkRequisition child_requisition;
137    gboolean switch_page = FALSE;
138    gint vis_pages;
139 -  gint focus_width;
140 +  gint focus_width, label_padding;
141 +  gint arrow_width, arrow_height, arrow_spacing, tab_overlap, tab_curvature;
142  
143 -  gtk_widget_style_get (widget, "focus-line-width", &focus_width, NULL);
144 +  gtk_widget_style_get (widget,
145 +                        "focus-line-width", &focus_width,
146 +                        "arrow-width", &arrow_width,
147 +                        "arrow-height", &arrow_height,
148 +                        "arrow-spacing", &arrow_spacing,
149 +                        "tab-overlap", &tab_overlap,
150 +                        "tab-curvature", &tab_curvature,
151 +                        "label-padding", &label_padding,
152 +                        NULL);
153    
154    widget->requisition.width = 0;
155    widget->requisition.height = 0;
156 @@ -1229,6 +1308,22 @@
157      {
158        widget->requisition.width += widget->style->xthickness * 2;
159        widget->requisition.height += widget->style->ythickness * 2;
160 +   
161 +      /* Hildon kludge: inner border paddings */
162 +      if (notebook->children && notebook->show_border)
163 +        {
164 +          gint inner_left_border, inner_right_border;
165 +
166 +          gtk_widget_style_get (widget,
167 +                                "inner_left_border",
168 +                                &inner_left_border,
169 +                                "inner_right_border",
170 +                                &inner_right_border,
171 +                                NULL);
172 +
173 +          widget->requisition.width += inner_left_border + inner_right_border;
174 +        }
175 +
176  
177        if (notebook->show_tabs)
178         {
179 @@ -1249,6 +1344,7 @@
180  
181                   gtk_widget_size_request (page->tab_label,
182                                            &child_requisition);
183 +                  child_requisition.width += 2 * label_padding;
184  
185                   page->requisition.width = 
186                     child_requisition.width +
187 @@ -1292,10 +1388,10 @@
188  
189                   if (notebook->scrollable && vis_pages > 1 && 
190                       widget->requisition.width < tab_width)
191 -                   tab_height = MAX (tab_height, ARROW_SIZE);
192 +                   tab_height = MAX (tab_height, arrow_height);
193  
194 -                 padding = 2 * (TAB_CURVATURE + focus_width +
195 -                                notebook->tab_hborder) - TAB_OVERLAP;
196 +                 padding = 2 * (tab_curvature + focus_width +
197 +                                notebook->tab_hborder) - tab_overlap;
198                   tab_max += padding;
199                   while (children)
200                     {
201 @@ -1316,15 +1412,15 @@
202  
203                   if (notebook->scrollable && vis_pages > 1 &&
204                       widget->requisition.width < tab_width)
205 -                   tab_width = tab_max + 2 * (ARROW_SIZE + ARROW_SPACING);
206 +                   tab_width = tab_max + 2 * (arrow_width + arrow_spacing);
207  
208                    if (notebook->homogeneous && !notebook->scrollable)
209                      widget->requisition.width = MAX (widget->requisition.width,
210                                                       vis_pages * tab_max +
211 -                                                     TAB_OVERLAP);
212 +                                                     tab_overlap);
213                    else
214                      widget->requisition.width = MAX (widget->requisition.width,
215 -                                                     tab_width + TAB_OVERLAP);
216 +                                                     tab_width + tab_overlap);
217  
218                   widget->requisition.height += tab_height;
219                   break;
220 @@ -1335,10 +1431,10 @@
221  
222                   if (notebook->scrollable && vis_pages > 1 && 
223                       widget->requisition.height < tab_height)
224 -                   tab_width = MAX (tab_width, ARROW_SPACING + 2 * ARROW_SIZE);
225 +                   tab_width = MAX (tab_width, arrow_spacing + 2 * arrow_width);
226  
227 -                 padding = 2 * (TAB_CURVATURE + focus_width +
228 -                                notebook->tab_vborder) - TAB_OVERLAP;
229 +                 padding = 2 * (tab_curvature + focus_width +
230 +                                notebook->tab_vborder) - tab_overlap;
231                   tab_max += padding;
232  
233                   while (children)
234 @@ -1361,24 +1457,24 @@
235  
236                   if (notebook->scrollable && vis_pages > 1 && 
237                       widget->requisition.height < tab_height)
238 -                   tab_height = tab_max + ARROW_SIZE + ARROW_SPACING;
239 +                   tab_height = tab_max + arrow_height + arrow_spacing;
240  
241                   widget->requisition.width += tab_width;
242  
243                    if (notebook->homogeneous && !notebook->scrollable)
244                      widget->requisition.height =
245                       MAX (widget->requisition.height,
246 -                          vis_pages * tab_max + TAB_OVERLAP);
247 +                          vis_pages * tab_max + tab_overlap);
248                    else
249                      widget->requisition.height =
250                       MAX (widget->requisition.height,
251 -                          tab_height + TAB_OVERLAP);
252 +                          tab_height + tab_overlap);
253  
254                   if (!notebook->homogeneous || notebook->scrollable)
255                     vis_pages = 1;
256                   widget->requisition.height = MAX (widget->requisition.height,
257                                                     vis_pages * tab_max +
258 -                                                   TAB_OVERLAP);
259 +                                                   tab_overlap);
260                   break;
261                 }
262             }
263 @@ -1499,7 +1595,26 @@
264             }
265         }
266  
267 +      /* Hildon kludge: inner border paddings */
268 +      if (notebook->show_border)
269 +        {
270 +          gint inner_left_border, inner_right_border;
271 +
272 +          gtk_widget_style_get (widget,
273 +                                "inner_left_border",
274 +                                &inner_left_border,
275 +                                "inner_right_border",
276 +                                &inner_right_border,
277 +                                NULL);
278 +
279 +          child_allocation.x += inner_left_border;
280 +          child_allocation.width -= inner_left_border + inner_right_border;
281 +          if (child_allocation.width < 0)
282 +            child_allocation.width = 0;
283 +        }
284 +
285        children = notebook->children;
286 +
287        while (children)
288         {
289           page = children->data;
290 @@ -1580,11 +1695,18 @@
291    GdkRectangle event_window_pos;
292    gboolean before = ARROW_IS_BEFORE (arrow);
293    gboolean left = ARROW_IS_LEFT (arrow);
294 +  gint arrow_width, arrow_height, arrow_spacing;
295 +
296 +  gtk_widget_style_get (GTK_WIDGET(notebook),
297 +                        "arrow-width", &arrow_width,
298 +                        "arrow-height", &arrow_height,
299 +                        "arrow-spacing", &arrow_spacing,
300 +                        NULL);
301  
302    if (gtk_notebook_get_event_window_position (notebook, &event_window_pos))
303      {
304 -      rectangle->width = ARROW_SIZE;
305 -      rectangle->height = ARROW_SIZE;
306 +      rectangle->width = arrow_width;
307 +      rectangle->height = arrow_height;
308  
309        switch (notebook->tab_pos)
310         {
311 @@ -1602,6 +1724,8 @@
312             rectangle->y += event_window_pos.height - rectangle->height;
313           break;
314         case GTK_POS_TOP:
315 +          arrow_spacing = - arrow_spacing;
316 +          /* Fall through */
317         case GTK_POS_BOTTOM:
318           if (before)
319             {
320 @@ -1617,7 +1741,11 @@
321               else
322                 rectangle->x = event_window_pos.x + event_window_pos.width - 2 * rectangle->width;
323             }
324 -         rectangle->y = event_window_pos.y + (event_window_pos.height - rectangle->height) / 2;
325 +         rectangle->y = event_window_pos.y;
326 +          if (arrow_spacing > 0)
327 +            rectangle->y += arrow_spacing;
328 +          else
329 +            rectangle->y += (event_window_pos.height - rectangle->height) / 2;
330           break;
331         }
332      }
333 @@ -1696,6 +1824,10 @@
334    gboolean is_rtl = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
335    gboolean left = (ARROW_IS_LEFT (arrow) && !is_rtl) || 
336                    (!ARROW_IS_LEFT (arrow) && is_rtl);
337 +  GtkSettings *settings = gtk_settings_get_default ();
338 +  guint timeout;
339 +
340 +  g_object_get (settings, "gtk-initial-timeout", &timeout, NULL);
341  
342    if (!GTK_WIDGET_HAS_FOCUS (widget))
343      gtk_widget_grab_focus (widget);
344 @@ -1706,14 +1838,14 @@
345    if (event->button == 1)
346      {
347        gtk_notebook_do_arrow (notebook, arrow);
348 -      
349 +
350        if (!notebook->timer)
351 -       {
352 -         notebook->timer = g_timeout_add (NOTEBOOK_INIT_SCROLL_DELAY, 
353 -                                          (GSourceFunc) gtk_notebook_timer, 
354 -                                          (gpointer) notebook);
355 -         notebook->need_timer = TRUE;
356 -       }
357 +        {
358 +          notebook->timer = g_timeout_add (timeout,
359 +                                           (GSourceFunc) gtk_notebook_timer,
360 +                                           (gpointer) notebook);
361 +          notebook->need_timer = TRUE;
362 +        }
363      }
364    else if (event->button == 2)
365      gtk_notebook_page_select (notebook, TRUE);
366 @@ -1862,7 +1994,7 @@
367  static void 
368  stop_scrolling (GtkNotebook *notebook)
369  {
370 -  if (notebook->timer)
371 +   if (notebook->timer)
372      {
373        g_source_remove (notebook->timer);
374        notebook->timer = 0;
375 @@ -2343,9 +2475,9 @@
376            */
377           return focus_child_in (notebook, GTK_DIR_TAB_FORWARD);
378         case GTK_DIR_LEFT:
379 -         return focus_tabs_move (notebook, direction, STEP_PREV);
380 +         return focus_tabs_move (notebook, direction, STEP_PREV_CYCLE);
381         case GTK_DIR_RIGHT:
382 -         return focus_tabs_move (notebook, direction, STEP_NEXT);
383 +         return focus_tabs_move (notebook, direction, STEP_NEXT_CYCLE);
384         }
385      }
386    else /* Focus was not on widget */
387 @@ -2481,7 +2613,6 @@
388   * gtk_notebook_redraw_tabs
389   * gtk_notebook_real_remove
390   * gtk_notebook_update_labels
391 - * gtk_notebook_timer
392   * gtk_notebook_page_compare
393   * gtk_notebook_real_page_position
394   * gtk_notebook_search_page
395 @@ -2574,22 +2705,27 @@
396  gtk_notebook_timer (GtkNotebook *notebook)
397  {
398    gboolean retval = FALSE;
399 +  guint timeout;
400 +  GtkSettings *settings;
401  
402    GDK_THREADS_ENTER ();
403  
404 +  settings = gtk_settings_get_default ();
405 +  g_object_get (settings, "gtk-update-timeout", &timeout, NULL);
406 +
407    if (notebook->timer)
408      {
409        gtk_notebook_do_arrow (notebook, notebook->click_child);
410  
411 -      if (notebook->need_timer) 
412 -       {
413 -         notebook->need_timer = FALSE;
414 -         notebook->timer = g_timeout_add (NOTEBOOK_SCROLL_DELAY,
415 -                                          (GSourceFunc) gtk_notebook_timer, 
416 -                                          (gpointer) notebook);
417 -       }
418 +      if (notebook->need_timer)
419 +        {
420 +          notebook->need_timer = FALSE;
421 +          notebook->timer = g_timeout_add (timeout,
422 +                                           (GSourceFunc) gtk_notebook_timer,
423 +                                           (gpointer) notebook);
424 +        }
425        else
426 -       retval = TRUE;
427 +        retval = TRUE;
428      }
429  
430    GDK_THREADS_LEAVE ();
431 @@ -2781,10 +2917,12 @@
432    switch (direction)
433      {
434      case STEP_PREV:
435 +    case STEP_PREV_CYCLE:
436        flag = GTK_PACK_END;
437        break;
438  
439      case STEP_NEXT:
440 +    case STEP_NEXT_CYCLE:
441        flag = GTK_PACK_START;
442        break;
443      }
444 @@ -2827,6 +2965,37 @@
445        old_list = list;
446        list = list->prev;
447      }
448 +
449 +  /* Hildon hack: keyboard navigation should cycle around */
450 +  if (direction == STEP_PREV_CYCLE)
451 +    {
452 +      /* find and return the last (visible) page */
453 +      list = g_list_last (notebook->children);
454 +      if (!find_visible)
455 +        return list;
456 +      while (list)
457 +        {
458 +          page = list->data;
459 +          if (GTK_WIDGET_VISIBLE (page->child))
460 +            return list;
461 +          list = list->prev;
462 +        }
463 +    }
464 +  if (direction == STEP_NEXT_CYCLE)
465 +    {
466 +      /* find and return the first (visible) page */
467 +      list = g_list_first (notebook->children);
468 +      if (!find_visible)
469 +        return list;
470 +      while (list)
471 +        {
472 +          page = list->data;
473 +          if (GTK_WIDGET_VISIBLE (page->child))
474 +            return list;
475 +          list = list->next;
476 +        }
477 +    }
478 +
479    return NULL;
480  }
481  
482 @@ -2850,6 +3019,7 @@
483    gint gap_x = 0, gap_width = 0, step = STEP_PREV;
484    gboolean is_rtl;
485    gint tab_pos;
486 +  gboolean paint_box_gap = FALSE;
487     
488    g_return_if_fail (GTK_IS_NOTEBOOK (widget));
489    g_return_if_fail (area != NULL);
490 @@ -2933,15 +3103,37 @@
491           step = STEP_PREV;
492           break;
493         }
494 -      gtk_paint_box_gap (widget->style, widget->window,
495 -                        GTK_STATE_NORMAL, GTK_SHADOW_OUT,
496 -                        area, widget, "notebook",
497 -                        x, y, width, height,
498 -                        tab_pos, gap_x, gap_width);
499 +
500 +      /* hildon hack to postpone painting until it
501 +         is known if scroll arrows will be drawn */
502 +      paint_box_gap = TRUE;
503      }
504  
505 +  /* first, figure out if arrows should be drawn */
506    showarrow = FALSE;
507    children = gtk_notebook_search_page (notebook, NULL, step, TRUE);
508 +  while (children && !showarrow)
509 +    {
510 +      page = children->data;
511 +      children = gtk_notebook_search_page (notebook, children,
512 +                                          step, TRUE);
513 +      if (!GTK_WIDGET_MAPPED (page->tab_label))
514 +       showarrow = TRUE;
515 +    }
516 +
517 +  /* then draw content area frame */
518 +  if (paint_box_gap)
519 +    gtk_paint_box_gap (widget->style, widget->window,
520 +                       GTK_STATE_NORMAL, GTK_SHADOW_OUT,
521 +                       area, widget,
522 +                       (showarrow && notebook->scrollable)
523 +                       ? "notebook_show_arrow"
524 +                       : "notebook",
525 +                       x, y, width, height,
526 +                       tab_pos, gap_x, gap_width);
527 +  
528 +  /* and finally draw tabs */
529 +  children = gtk_notebook_search_page (notebook, NULL, step, TRUE);
530    while (children)
531      {
532        page = children->data;
533 @@ -3069,10 +3261,15 @@
534    GdkRectangle arrow_rect;
535    GtkArrowType arrow;
536    gboolean is_rtl, left;
537 +  gint arrow_width, arrow_height;
538  
539    gtk_notebook_get_arrow_rect (notebook, &arrow_rect, nbarrow);
540  
541    widget = GTK_WIDGET (notebook);
542 +  gtk_widget_style_get (widget,
543 +                        "arrow-width", &arrow_width,
544 +                        "arrow-height", &arrow_height,
545 +                        NULL);
546  
547    is_rtl = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
548    left = (ARROW_IS_LEFT (nbarrow) && !is_rtl) ||
549 @@ -3112,7 +3309,7 @@
550        gtk_paint_arrow (widget->style, widget->window, state_type, 
551                        shadow_type, NULL, widget, "notebook",
552                        arrow, TRUE, arrow_rect.x, arrow_rect.y, 
553 -                      ARROW_SIZE, ARROW_SIZE);
554 +                      arrow_width, arrow_height);
555      }
556  }
557  
558 @@ -3143,13 +3340,25 @@
559    gboolean is_rtl = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL &&
560                      (tab_pos == GTK_POS_TOP || tab_pos == GTK_POS_BOTTOM));
561    gint memo_x;
562 +  gboolean truncate = FALSE;
563 +  gint arrow_width, arrow_height, arrow_spacing, tab_overlap;
564 +  gint total_width, ideal_tab_width, n_expanding_tabs;
565  
566    if (!notebook->show_tabs || !notebook->children || !notebook->cur_page)
567      return;
568  
569 +  gtk_widget_style_get (widget,
570 +                        "arrow-width", &arrow_width,
571 +                        "arrow-height", &arrow_height,
572 +                        "arrow-spacing", &arrow_spacing,
573 +                        "tab-overlap", &tab_overlap,
574 +                        NULL);
575 +
576    child_allocation.x = widget->allocation.x + container->border_width;
577    child_allocation.y = widget->allocation.y + container->border_width;
578  
579 +  total_width = allocation->width - 2 * container->border_width - tab_overlap;
580 +
581    switch (tab_pos)
582      {
583      case GTK_POS_BOTTOM:
584 @@ -3198,27 +3407,26 @@
585               if (GTK_WIDGET_VISIBLE (page->child))
586                 tab_space += page->requisition.width;
587             }
588 -         if (tab_space >
589 -             allocation->width - 2 * container->border_width - TAB_OVERLAP) 
590 +         if (tab_space > total_width) 
591             {
592               showarrow = TRUE;
593               page = focus_tab->data; 
594  
595 -             tab_space = allocation->width - TAB_OVERLAP -
596 +             tab_space = allocation->width - tab_overlap -
597                 page->requisition.width - 2 * container->border_width;
598               if (notebook->has_after_previous)
599 -               tab_space -= ARROW_SPACING + ARROW_SIZE;
600 +               tab_space -= arrow_spacing + arrow_width;
601               if (notebook->has_after_next)
602 -               tab_space -= ARROW_SPACING + ARROW_SIZE;
603 +               tab_space -= arrow_spacing + arrow_width;
604               if (notebook->has_before_previous)
605                 {
606 -                 tab_space -= ARROW_SPACING + ARROW_SIZE;
607 -                 child_allocation.x += ARROW_SPACING + ARROW_SIZE;
608 +                 tab_space -= arrow_spacing + arrow_width;
609 +                 child_allocation.x += arrow_spacing + arrow_width;
610                 }
611               if (notebook->has_before_next)
612                 {
613 -                 tab_space -= ARROW_SPACING + ARROW_SIZE;
614 -                 child_allocation.x += ARROW_SPACING + ARROW_SIZE;
615 +                 tab_space -= arrow_spacing + arrow_width;
616 +                 child_allocation.x += arrow_spacing + arrow_width;
617                 }
618             }
619           break;
620 @@ -3233,19 +3441,19 @@
621                 tab_space += page->requisition.height;
622             }
623           if (tab_space >
624 -             (allocation->height - 2 * container->border_width - TAB_OVERLAP))
625 +             (allocation->height - 2 * container->border_width - tab_overlap))
626             {
627               showarrow = TRUE;
628               page = focus_tab->data; 
629               tab_space = allocation->height
630 -               - TAB_OVERLAP - 2 * container->border_width
631 +               - tab_overlap - 2 * container->border_width
632                 - page->requisition.height;
633               if (notebook->has_after_previous || notebook->has_after_next)
634 -               tab_space -= ARROW_SPACING + ARROW_SIZE;
635 +               tab_space -= arrow_spacing + arrow_height;
636               if (notebook->has_before_previous || notebook->has_before_next)
637                 {
638 -                 tab_space -= ARROW_SPACING + ARROW_SIZE;
639 -                 child_allocation.y += ARROW_SPACING + ARROW_SIZE;
640 +                 tab_space -= arrow_spacing + arrow_height;
641 +                 child_allocation.y += arrow_spacing + arrow_height;
642                 }
643             }
644           break;
645 @@ -3257,6 +3465,10 @@
646               notebook->first_tab = focus_tab;
647               last_child = gtk_notebook_search_page (notebook, focus_tab,
648                                                      STEP_NEXT, TRUE);
649 +
650 +              /* Hildon: there is only one visible tab label
651 +                 and it doesn't fit unless it is truncated */
652 +              truncate = TRUE;
653             }
654           else
655             {
656 @@ -3413,7 +3625,7 @@
657             }
658           tab_space -= allocation->height;
659         }
660 -      tab_space += 2 * container->border_width + TAB_OVERLAP;
661 +      tab_space += 2 * container->border_width + tab_overlap;
662        tab_space *= -1;
663        notebook->first_tab = gtk_notebook_search_page (notebook, NULL,
664                                                       STEP_NEXT, TRUE);
665 @@ -3432,12 +3644,29 @@
666        if (showarrow) 
667         {
668           if (notebook->has_after_previous)
669 -           child_allocation.x -= ARROW_SPACING + ARROW_SIZE;
670 +           child_allocation.x -= arrow_spacing + arrow_width;
671           if (notebook->has_after_next)
672 -           child_allocation.x -= ARROW_SPACING + ARROW_SIZE;
673 +           child_allocation.x -= arrow_spacing + arrow_width;
674         }
675       }
676  
677 +  ideal_tab_width = (total_width / n);
678 +  n_expanding_tabs = 0;
679 +
680 +  while (children)
681 +    {
682 +      if (children == last_child)
683 +        break;
684 +
685 +      page = children->data;
686 +      children = gtk_notebook_search_page (notebook, children, STEP_NEXT,TRUE);
687 +
688 +      if (page->requisition.width <= ideal_tab_width)
689 +        n_expanding_tabs++;
690 +    }
691 +
692 +  children = notebook->first_tab;
693 +
694    while (children)
695      {
696        if (children == last_child)
697 @@ -3452,9 +3681,11 @@
698        children = gtk_notebook_search_page (notebook, children, STEP_NEXT,TRUE);
699        
700        delta = 0;
701 -      if (n && (showarrow || page->expand || notebook->homogeneous))
702 +
703 +      if (n && (showarrow || page->expand || notebook->homogeneous) &&
704 +          (page->requisition.width <= ideal_tab_width))
705         {
706 -         new_fill = (tab_space * i++) / n;
707 +         new_fill = (tab_space * i++) / n_expanding_tabs;
708           delta = new_fill - old_fill;
709           old_fill = new_fill;
710         }
711 @@ -3463,15 +3694,18 @@
712         {
713         case GTK_POS_TOP:
714         case GTK_POS_BOTTOM:
715 +          if (truncate)
716 +            delta *= -1;
717 +
718           child_allocation.width = (page->requisition.width +
719 -                                   TAB_OVERLAP + delta);
720 +                                   tab_overlap + delta);
721            if (is_rtl)
722               child_allocation.x -= child_allocation.width;
723           break;
724         case GTK_POS_LEFT:
725         case GTK_POS_RIGHT:
726           child_allocation.height = (page->requisition.height +
727 -                                    TAB_OVERLAP + delta);
728 +                                    tab_overlap + delta);
729           break;
730         }
731  
732 @@ -3482,13 +3716,13 @@
733         case GTK_POS_TOP:
734         case GTK_POS_BOTTOM:
735            if (!is_rtl)
736 -            child_allocation.x += child_allocation.width - TAB_OVERLAP;
737 +            child_allocation.x += child_allocation.width - tab_overlap;
738            else
739 -             child_allocation.x += TAB_OVERLAP;
740 +             child_allocation.x += tab_overlap;
741           break;
742         case GTK_POS_LEFT:
743         case GTK_POS_RIGHT:
744 -         child_allocation.y += child_allocation.height - TAB_OVERLAP;
745 +         child_allocation.y += child_allocation.height - tab_overlap;
746           break;
747         }
748  
749 @@ -3538,14 +3772,14 @@
750             case GTK_POS_TOP:
751             case GTK_POS_BOTTOM:
752               child_allocation.width = (page->requisition.width +
753 -                                       TAB_OVERLAP + delta);
754 +                                       tab_overlap + delta);
755                if (!is_rtl)
756                  child_allocation.x -= child_allocation.width;
757               break;
758             case GTK_POS_LEFT:
759             case GTK_POS_RIGHT:
760               child_allocation.height = (page->requisition.height +
761 -                                        TAB_OVERLAP + delta);
762 +                                        tab_overlap + delta);
763               child_allocation.y -= child_allocation.height;
764               break;
765             }
766 @@ -3557,13 +3791,13 @@
767             case GTK_POS_TOP:
768             case GTK_POS_BOTTOM:
769                if (!is_rtl)
770 -                child_allocation.x += TAB_OVERLAP;
771 +                child_allocation.x += tab_overlap;
772                else
773 -                 child_allocation.x += child_allocation.width - TAB_OVERLAP;
774 +                 child_allocation.x += child_allocation.width - tab_overlap;
775               break;
776             case GTK_POS_LEFT:
777             case GTK_POS_RIGHT:
778 -             child_allocation.y += TAB_OVERLAP;
779 +             child_allocation.y += tab_overlap;
780               break;
781             }
782  
783 @@ -3589,8 +3823,12 @@
784    gint padding;
785    gint focus_width;
786    gint tab_pos = get_effective_tab_pos (notebook);
787 +  gint tab_curvature;
788  
789 -  gtk_widget_style_get (widget, "focus-line-width", &focus_width, NULL);
790 +  gtk_widget_style_get (widget,
791 +                        "focus-line-width", &focus_width,
792 +                        "tab-curvature", &tab_curvature,
793 +                        NULL);
794    
795    xthickness = widget->style->xthickness;
796    ythickness = widget->style->ythickness;
797 @@ -3621,7 +3859,7 @@
798      {
799      case GTK_POS_TOP:
800      case GTK_POS_BOTTOM:
801 -      padding = TAB_CURVATURE + focus_width + notebook->tab_hborder;
802 +      padding = tab_curvature + focus_width + notebook->tab_hborder;
803        if (page->fill)
804         {
805           child_allocation.x = (xthickness + focus_width +
806 @@ -3646,7 +3884,7 @@
807        break;
808      case GTK_POS_LEFT:
809      case GTK_POS_RIGHT:
810 -      padding = TAB_CURVATURE + focus_width + notebook->tab_vborder;
811 +      padding = tab_curvature + focus_width + notebook->tab_vborder;
812        if (page->fill)
813         {
814           child_allocation.y = ythickness + padding;
815 @@ -4340,7 +4578,7 @@
816      }
817    page->tab_label = tab_label;
818    page->menu_label = menu_label;
819 -  page->expand = FALSE;
820 +  page->expand = TRUE;
821    page->fill = TRUE;
822    page->pack = GTK_PACK_START; 
823  
824 @@ -5046,6 +5284,7 @@
825      {
826        page->default_tab = FALSE;
827        page->tab_label = tab_label;
828 +
829        gtk_widget_set_parent (page->tab_label, GTK_WIDGET (notebook));
830      }
831    else