]> pilppa.org Git - familiar-h63xx-build.git/blob - org.handhelds.familiar/packages/gtk+/gtk+-2.6.4-1.osso7/gtkcombobox.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 / gtkcombobox.c.diff
1 --- gtk+-2.6.4/gtk/gtkcombobox.c        2005-02-25 21:11:08.000000000 +0200
2 +++ gtk+-2.6.4/gtk/gtkcombobox.c        2005-04-06 16:19:36.406003808 +0300
3 @@ -17,6 +17,10 @@
4   * Boston, MA 02111-1307, USA.
5   */
6  
7 +/*
8 + * Modified for Nokia Oyj during 2002-2004. 
9 + */
10 +
11  #include <config.h>
12  #include "gtkalias.h"
13  #include "gtkcombobox.h"
14 @@ -39,6 +43,8 @@
15  #include "gtktreeselection.h"
16  #include "gtkvseparator.h"
17  #include "gtkwindow.h"
18 +#include "gtkcomboboxentry.h"
19 +#include "gtktoolbar.h"
20  
21  #include <gdk/gdkkeysyms.h>
22  
23 @@ -52,6 +58,13 @@
24  
25  #include "gtktreeprivate.h"
26  
27 +#define HILDON_MAX_WIDTH 406
28 +#define HILDON_MAX_HEIGHT 305
29 +#define HILDON_MAX_ITEMS 8
30 +/* this is also defined in gtkmenu.c and should be replaced with
31 +  a style property */
32 +#define MENU_SCROLL_ARROW_HEIGHT 20 
33 +
34  /* WELCOME, to THE house of evil code */
35  
36  typedef struct _ComboCellInfo ComboCellInfo;
37 @@ -119,6 +132,9 @@
38    GtkTreeViewRowSeparatorFunc row_separator_func;
39    gpointer                    row_separator_data;
40    GtkDestroyNotify            row_separator_destroy;
41 +
42 +  /* Hildon hack: state of our style property */
43 +  gboolean autodimmed_button;
44  };
45  
46  /* While debugging this evil code, I have learned that
47 @@ -201,6 +217,7 @@
48  
49  #define BONUS_PADDING 4
50  #define SCROLL_TIME  100
51 +#define HILDON_PADDING 25
52  
53  /* common */
54  static void     gtk_combo_box_class_init           (GtkComboBoxClass *klass);
55 @@ -273,6 +290,14 @@
56                                                      gboolean          include_internals,
57                                                      GtkCallback       callback,
58                                                      gpointer          callback_data);
59 +static gboolean gtk_combo_box_focus_in             (GtkWidget        *widget,
60 +                                                    GdkEventFocus    *event);
61 +static gint gtk_combo_box_focus             (GtkWidget        *widget,
62 +                                                    GtkDirectionType dir);
63 +static void gtk_combo_box_child_focus_in            (GtkWidget        *widget,
64 +                                                    GdkEventFocus    *event);
65 +static void gtk_combo_box_child_focus_out            (GtkWidget        *widget,
66 +                                                    GdkEventFocus    *event);
67  static gboolean gtk_combo_box_expose_event         (GtkWidget        *widget,
68                                                      GdkEventExpose   *event);
69  static gboolean gtk_combo_box_scroll_event         (GtkWidget        *widget,
70 @@ -285,6 +310,12 @@
71  
72  static void     gtk_combo_box_check_appearance     (GtkComboBox      *combo_box);
73  
74 +/* <Hildon addition> */
75 +extern void     gtk_grab_combo_box_entry_focus   (GtkComboBoxEntry *entry_box);
76 +
77 +static void    gtk_combo_box_grab_focus         (GtkWidget         *focus_widget);
78 +/* </hildon addition> */
79 +
80  /* listening to the model */
81  static void     gtk_combo_box_model_row_inserted   (GtkTreeModel     *model,
82                                                     GtkTreePath      *path,
83 @@ -424,6 +455,9 @@
84  static void gtk_combo_box_start_editing (GtkCellEditable *cell_editable,
85                                          GdkEvent        *event);
86  
87 +static void gtk_combo_box_menu_position_above (GtkMenu  *menu, gint     *x,
88 +                                              gint     *y, gboolean *push_in,
89 +                                              gpointer  user_data);
90  
91  GType
92  gtk_combo_box_get_type (void)
93 @@ -479,6 +513,25 @@
94    return combo_box_type;
95  }
96  
97 +/* Hildon addition: Check if the button needs to be dimmed */
98 +static void hildon_check_autodim(GtkComboBox *combo_box)
99 +{
100 +  GtkWidget *widget;
101 +  GtkTreeModel *model;
102 +  GtkTreeIter iter;
103 +
104 +  widget = combo_box->priv->button;
105 +  model = combo_box->priv->model;
106 +
107 +  if (combo_box->priv->autodimmed_button && widget != NULL)
108 +    {
109 +      if (model && gtk_tree_model_get_iter_first(model, &iter))
110 +        gtk_widget_set_sensitive(widget, TRUE);
111 +      else 
112 +        gtk_widget_set_sensitive(widget, FALSE);
113 +    }
114 +}
115 +
116  /* common */
117  static void
118  gtk_combo_box_class_init (GtkComboBoxClass *klass)
119 @@ -504,6 +557,11 @@
120    widget_class->mnemonic_activate = gtk_combo_box_mnemonic_activate;
121    widget_class->style_set = gtk_combo_box_style_set;
122    widget_class->state_changed = gtk_combo_box_state_changed;
123 +  
124 +  /* Hildon addition */
125 +  widget_class->grab_focus = gtk_combo_box_grab_focus;
126 +  widget_class->focus_in_event = gtk_combo_box_focus_in;
127 +  widget_class->focus = gtk_combo_box_focus;
128  
129    gtk_object_class = (GtkObjectClass *)klass;
130    gtk_object_class->destroy = gtk_combo_box_destroy;
131 @@ -687,6 +745,41 @@
132                                                                   FALSE,
133                                                                   G_PARAM_READABLE));
134  
135 +  gtk_widget_class_install_style_property (widget_class,
136 +                                  g_param_spec_boolean ("hildonlike",
137 +                                  _("Size request"),
138 +                                 _("Size allocate"),
139 +                                  FALSE,
140 +                                  G_PARAM_READABLE));
141 +
142 +  gtk_widget_class_install_style_property (widget_class,
143 +                                          g_param_spec_int ("arrow-height",
144 +                                                             P_("Arrow height for option menu"),
145 +                                                             P_("Sets arrow height"),
146 +                                                             0,
147 +                                                             G_MAXINT,
148 +                                                             28,
149 +                                                             G_PARAM_READWRITE));
150 +
151 +  gtk_widget_class_install_style_property (widget_class,
152 +                                          g_param_spec_int ("arrow-width",
153 +                                                             P_("Arrow width for option menu"),
154 +                                                             P_("Sets arrow width"),
155 +                                                             0,
156 +                                                             G_MAXINT,
157 +                                                             26,
158 +                                                             G_PARAM_READWRITE));
159 +
160 +
161 +  /* Hildon hack: style property for enabling the autodimming hack */
162 +  gtk_widget_class_install_style_property (
163 +    widget_class,
164 +    g_param_spec_boolean ("autodimmed_button",
165 +    _("Autodimmed button"),
166 +    _("Automatically dims the button if the list is empty"),
167 +    FALSE,
168 +    G_PARAM_READABLE));
169 +
170    g_type_class_add_private (object_class, sizeof (GtkComboBoxPrivate));
171  }
172  
173 @@ -731,6 +824,11 @@
174    combo_box->priv->editing_canceled = FALSE;
175    combo_box->priv->auto_scroll = FALSE;
176    combo_box->priv->focus_on_click = TRUE;
177 +
178 +  /* Hildon hack: default value for our style property if it is queried before
179 +   *              the style is set */
180 +  combo_box->priv->autodimmed_button = FALSE;
181 +  GTK_WIDGET_SET_FLAGS ( combo_box, GTK_CAN_FOCUS );
182  }
183  
184  static void
185 @@ -911,7 +1009,19 @@
186  {
187    GtkComboBox *combo_box = GTK_COMBO_BOX (widget);
188  
189 +  /* Hildon hack: read the state of our style property */
190 +  gtk_widget_style_get (GTK_WIDGET(combo_box),
191 +    "autodimmed_button", &(combo_box->priv->autodimmed_button), NULL);
192 +  
193    gtk_combo_box_check_appearance (combo_box);
194 +  
195 +  /* Hildon hack: handle the dimmed state of the button in regards whether
196 +   *              the list is empty or not. This has to be done here because
197 +   *              in the callback functions of GtkTreeModel the button widget
198 +   *              may have not yet been set. However, we repeat this stuff in
199 +   *              those functions, because later the button will be set and
200 +   *              we want to update our state. */
201 +  hildon_check_autodim(combo_box);
202  
203    if (combo_box->priv->tree_view && combo_box->priv->cell_view)
204      gtk_cell_view_set_background_color (GTK_CELL_VIEW (combo_box->priv->cell_view), 
205 @@ -922,10 +1032,17 @@
206  gtk_combo_box_button_toggled (GtkWidget *widget,
207                                gpointer   data)
208  {
209 +  gboolean hildonlike;
210    GtkComboBox *combo_box = GTK_COMBO_BOX (data);
211 +  
212 +  gtk_widget_style_get (GTK_WIDGET (combo_box), "hildonlike", &hildonlike, NULL);
213  
214    if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
215      {
216 +       if (hildonlike) {
217 +         gtk_combo_box_grab_focus(GTK_WIDGET(combo_box));
218 +       }
219 +      
220        if (!combo_box->priv->popup_in_progress)
221          gtk_combo_box_popup (combo_box);
222      }
223 @@ -1103,7 +1220,7 @@
224      {
225        gtk_container_remove (GTK_CONTAINER (combo_box->priv->popup_frame),
226                              combo_box->priv->popup_widget);
227 -      g_object_unref (combo_box->priv->popup_widget);
228 +      g_object_unref (G_OBJECT (combo_box->priv->popup_widget));
229        combo_box->priv->popup_widget = NULL;
230      }
231  
232 @@ -1175,7 +1292,7 @@
233                           popup);
234  
235        gtk_widget_show (popup);
236 -      g_object_ref (popup);
237 +      g_object_ref (G_OBJECT (popup));
238        combo_box->priv->popup_widget = popup;
239      }
240  }
241 @@ -1250,9 +1367,13 @@
242    GtkRequisition requisition;
243    GList *children;
244    gint screen_width;
245 +  gint screen_height;
246    gint menu_xpos;
247    gint menu_ypos;
248 -  gint menu_width;
249 +  gint menu_width, menu_height;
250 +  gint counter = 0;
251 +  gint scroll_offset = 0;
252 +  gint max_items = 0;
253  
254    g_return_if_fail (GTK_IS_COMBO_BOX (user_data));
255    
256 @@ -1261,6 +1382,7 @@
257  
258    gtk_widget_get_child_requisition (GTK_WIDGET (menu), &requisition);
259    menu_width = requisition.width;
260 +  menu_height = requisition.height;
261  
262    active = gtk_menu_get_active (GTK_MENU (combo_box->priv->popup_widget));
263    gdk_window_get_origin (widget->window, &menu_xpos, &menu_ypos);
264 @@ -1275,6 +1397,11 @@
265      }
266  
267    children = GTK_MENU_SHELL (combo_box->priv->popup_widget)->children;
268 +  child = children->data;
269 +  gtk_widget_get_child_requisition (child, &requisition);
270 +  max_items = (HILDON_MAX_HEIGHT-2*MENU_SCROLL_ARROW_HEIGHT)/requisition.height;
271 +  max_items -= 1;
272 +  
273    while (children)
274      {
275        child = children->data;
276 @@ -1284,27 +1411,119 @@
277  
278        if (GTK_WIDGET_VISIBLE (child))
279         {
280 -         gtk_widget_get_child_requisition (child, &requisition);
281 -         menu_ypos -= requisition.height;
282 +          if (counter < max_items - 2)
283 +              menu_ypos -= requisition.height;
284 +          if (counter > max_items - 3)
285 +              scroll_offset += requisition.height;        
286         }
287 -
288 +      
289 +      counter++;
290        children = children->next;
291      }
292 +  gtk_widget_get_child_requisition (GTK_WIDGET(menu), &requisition);
293  
294 +  if ( requisition.height >= HILDON_MAX_HEIGHT )
295 +      menu_ypos -= MENU_SCROLL_ARROW_HEIGHT;
296 +  
297    if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
298      menu_xpos = menu_xpos + widget->allocation.width - menu_width;
299  
300 +  {
301 +    gint menu_xpad, menu_ypad;
302 +    gtk_widget_style_get (GTK_WIDGET (menu),
303 +    "horizontal-padding", &menu_xpad,
304 +    "vertical-padding", &menu_ypad,
305 +    NULL);
306 +    menu_xpos -= menu_xpad - 3;
307 +    menu_ypos -= menu_ypad - 1;
308 +  }
309 +
310    /* Clamp the position on screen */
311    screen_width = gdk_screen_get_width (gtk_widget_get_screen (widget));
312 +  screen_height = gdk_screen_get_height (gtk_widget_get_screen (widget));
313    
314    if (menu_xpos < 0)
315      menu_xpos = 0;
316    else if ((menu_xpos + menu_width) > screen_width)
317      menu_xpos -= ((menu_xpos + menu_width) - screen_width);
318  
319 +  if (menu_ypos + menu_height > screen_height)
320 +  {
321 +      menu_ypos = screen_height - menu_height;
322 +  }
323 +  if (menu_ypos < 0)
324 +  {
325 +      menu_ypos = 0;
326 +  }
327 +
328 +  GTK_MENU(combo_box->priv->popup_widget)->scroll_offset = scroll_offset;
329 +  
330    *x = menu_xpos;
331    *y = menu_ypos;
332  
333 +  *push_in = FALSE;
334 +}
335 +
336 +static void 
337 +gtk_combo_box_menu_position_above (GtkMenu  *menu,
338 +                                  gint     *x,
339 +                                  gint     *y,
340 +                                  gboolean *push_in,
341 +                                  gpointer  user_data)
342 +{
343 +  /* 
344 +   * This function positiones the menu above widgets.
345 +   * This is a modified version of the position function 
346 +   * gtk_combo_box_position_over. 
347 +   * NB: This is only used when gtkcombobox is in toolbar!
348 +   */
349 +
350 +  GtkWidget *child;
351 +  GtkRequisition requisition;
352 +  GList *children;
353 +  gint screen_width;
354 +  gint menu_xpos;
355 +  gint menu_ypos;
356 +  gint gx,gy;
357 +  gint menu_width;
358 +  GtkWidget *widget;
359 +
360 +  widget = GTK_WIDGET(user_data);
361 +
362 +  gtk_widget_get_child_requisition (GTK_WIDGET (menu), &requisition);
363 +  menu_width = requisition.width;
364 +
365 +  gdk_window_get_position(GDK_WINDOW(widget->window), &gx, &gy);
366 +  gtk_widget_translate_coordinates (widget, gtk_widget_get_toplevel(widget),
367 +                                    gx, gy, &menu_xpos, &menu_ypos);
368 +
369 +  menu_ypos -= GTK_WIDGET(menu)->style->ythickness * 2;
370 +  menu_ypos -= GTK_WIDGET(widget)->style->ythickness * 2;
371 +
372 +  menu_ypos -= widget->allocation.height;
373 +
374 +  children = GTK_MENU_SHELL (menu)->children;
375 +  while (children) {
376 +    child = children->data;    
377 +    if (GTK_WIDGET_VISIBLE (child)){      
378 +      gtk_widget_get_child_requisition (child, &requisition);
379 +      menu_ypos -= requisition.height;
380 +    }
381 +    children = children->next;
382 +  }
383 +
384 +  if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
385 +    menu_xpos = menu_xpos + widget->allocation.width - menu_width;
386 +
387 +  screen_width = gdk_screen_get_width (gtk_widget_get_screen (widget));
388 +  
389 +  if (menu_xpos < 0)
390 +    menu_xpos = 0;
391 +  else if ((menu_xpos + menu_width) > screen_width)
392 +    menu_xpos -= ((menu_xpos + menu_width) - screen_width);
393 +
394 +  *x = menu_xpos;
395 +  *y = menu_ypos;
396    *push_in = TRUE;
397  }
398  
399 @@ -1318,21 +1537,44 @@
400    GtkComboBox *combo_box;
401    GtkWidget *menu_item;
402  
403 +  gboolean hildonlike;
404 +
405    combo_box = GTK_COMBO_BOX (user_data);
406  
407 -  if (combo_box->priv->wrap_width > 0 || combo_box->priv->cell_view == NULL)   
408 -    gtk_combo_box_menu_position_below (menu, x, y, push_in, user_data);
409 -  else
410 +  gtk_widget_style_get (GTK_WIDGET (combo_box), "hildonlike", &hildonlike, NULL);
411 +
412 +  if (!(combo_box->priv->wrap_width > 0 || combo_box->priv->cell_view == NULL))
413      {
414        /* FIXME handle nested menus better */
415        menu_item = gtk_menu_get_active (GTK_MENU (combo_box->priv->popup_widget));
416        if (menu_item)
417         gtk_menu_shell_select_item (GTK_MENU_SHELL (combo_box->priv->popup_widget), 
418                                     menu_item);
419 +    }
420  
421 -      gtk_combo_box_menu_position_over (menu, x, y, push_in, user_data);
422 +  if (hildonlike) 
423 +    {
424 +      /* HILDON: we check if combobox is in a toolbar */
425 +      gboolean in_toolbar = gtk_widget_get_ancestor(GTK_WIDGET(combo_box), GTK_TYPE_TOOLBAR) != NULL;
426 +      if (in_toolbar)
427 +       {
428 +         /*due to limits in combo's sizes we use position_over here also*/
429 +          gtk_combo_box_menu_position_over (menu, x, y, push_in, user_data);   
430 +         return;
431 +       }
432      }
433  
434 +  if (combo_box->priv->wrap_width > 0 || combo_box->priv->cell_view == NULL)   
435 +/*
436 + * Changed because we always want the combo box position to be over
437 + * the combo box, unless it's in toolbar.
438 + *
439 +    gtk_combo_box_menu_position_below (menu, x, y, push_in, user_data);
440 +*/
441 +    gtk_combo_box_menu_position_over (menu, x, y, push_in, user_data);       
442 +  else
443 +    gtk_combo_box_menu_position_over (menu, x, y, push_in, user_data);       
444 +
445  }
446  
447  static void
448 @@ -1430,7 +1672,7 @@
449    list = cells;
450    while (list)
451      {
452 -      g_object_get (list->data, "sensitive", &sensitive, NULL);
453 +      g_object_get (G_OBJECT (list->data), "sensitive", &sensitive, NULL);
454        
455        if (sensitive)
456         break;
457 @@ -1469,7 +1711,7 @@
458    list = cells;
459    while (list)
460      {
461 -      g_object_get (list->data, "sensitive", &sensitive, NULL);
462 +      g_object_get (G_OBJECT (list->data), "sensitive", &sensitive, NULL);
463        
464        if (sensitive)
465         break;
466 @@ -1516,8 +1758,8 @@
467           if (menu != combo_box->priv->popup_widget && child == children)
468             {
469               separator = GTK_WIDGET (child->next->data);
470 -             g_object_set (item, "visible", sensitive, NULL);
471 -             g_object_set (separator, "visible", sensitive, NULL);
472 +             g_object_set (G_OBJECT (item), "visible", sensitive, NULL);
473 +             g_object_set (G_OBJECT (separator), "visible", sensitive, NULL);
474             }
475           else
476             gtk_widget_set_sensitive (item, sensitive);
477 @@ -1543,16 +1785,19 @@
478    if (gtk_tree_row_reference_valid (combo_box->priv->active_row))
479      {
480        path = gtk_tree_row_reference_get_path (combo_box->priv->active_row);
481 -      active_item = gtk_tree_path_get_indices (path)[0];
482 -      gtk_tree_path_free (path);
483 -      
484 -      if (combo_box->priv->add_tearoffs)
485 -       active_item++;
486 +      if (path)
487 +       {
488 +         active_item = gtk_tree_path_get_indices (path)[0];
489 +         gtk_tree_path_free (path);
490 +
491 +         if (combo_box->priv->add_tearoffs)
492 +           active_item++;
493 +       }
494      }
495  
496    /* FIXME handle nested menus better */
497 -  gtk_menu_set_active (GTK_MENU (combo_box->priv->popup_widget), active_item);
498 -  
499 +  gtk_menu_set_active (GTK_MENU (combo_box->priv->popup_widget), active_item);  
500 +     
501    if (combo_box->priv->wrap_width == 0)
502      {
503        width = GTK_WIDGET (combo_box)->allocation.width;
504 @@ -1684,6 +1929,7 @@
505  {
506    gint padding;
507    GtkRequisition req;
508 +  gboolean hildonlike;
509  
510    if (combo_box->priv->cell_view)
511      gtk_widget_style_get (combo_box->priv->cell_view,
512 @@ -1691,9 +1937,17 @@
513                            NULL);
514    else
515      padding = 0;
516 +  
517 +   gtk_widget_style_get (GTK_WIDGET (combo_box), "hildonlike", &hildonlike,
518 +                        NULL);
519  
520    /* add some pixels for good measure */
521 -  padding += BONUS_PADDING;
522 +  /* Hildon: we need more padding because our theming
523 +   * Not elegent way to do it anyway ... */
524 +  if (hildonlike)
525 +    padding += HILDON_PADDING;
526 +  else
527 +    padding += BONUS_PADDING;
528  
529    if (combo_box->priv->cell_view)
530      gtk_cell_view_get_size_of_row (GTK_CELL_VIEW (combo_box->priv->cell_view),
531 @@ -1709,6 +1963,7 @@
532  {
533    GtkTreeIter iter;
534    GtkTreePath *path;
535 +  gboolean hildonlike;
536  
537    if (!combo_box->priv->model ||
538        !gtk_tree_model_get_iter_first (combo_box->priv->model, &iter))
539 @@ -1717,6 +1972,7 @@
540    combo_box->priv->width = 0;
541  
542    path = gtk_tree_path_new_from_indices (0, -1);
543 +  gtk_widget_style_get (GTK_WIDGET (combo_box), "hildonlike", &hildonlike, NULL);
544  
545    do
546      {
547 @@ -1727,8 +1983,11 @@
548                                         path, &req);
549        else
550          req.width = 0;
551 +  /* Hildon: we need more padding because our theming
552 +   * Not elegent way to do it anyway ... */
553  
554 -      combo_box->priv->width = MAX (combo_box->priv->width, req.width);
555 +      combo_box->priv->width = MAX (combo_box->priv->width,
556 +                                    req.width + (hildonlike == 1) ? HILDON_PADDING : 0 );
557  
558        gtk_tree_path_next (path);
559      }
560 @@ -1744,10 +2003,19 @@
561    gint width, height;
562    gint focus_width, focus_pad;
563    GtkRequisition bin_req;
564 +  gboolean hildonlike;
565 +  gint arrow_width;
566 +  gint arrow_height;
567  
568    GtkComboBox *combo_box = GTK_COMBO_BOX (widget);
569  
570    gtk_combo_box_check_appearance (combo_box);
571 +  
572 +  /* get hildonlike style property */
573 +  gtk_widget_style_get (widget, "hildonlike",
574 +                       &hildonlike, "arrow-width",
575 +                       &arrow_width, "arrow-height",
576 +                       &arrow_height, NULL);
577  
578    /* common */
579    gtk_widget_size_request (GTK_BIN (widget)->child, &bin_req);
580 @@ -1829,6 +2097,13 @@
581        requisition->height = MAX (requisition->height, button_req.height);
582        requisition->width += button_req.width;
583      }
584 +
585 +  requisition->width = MIN (requisition->width, HILDON_MAX_WIDTH);
586 +  
587 +  /* HILDON quick fix: height forced to be 28px as specified by Hildon specs. */
588 +  if (hildonlike)
589 +    if (requisition->height > arrow_height)
590 +      requisition->height = arrow_height;
591  }
592  
593  static void
594 @@ -1839,17 +2114,32 @@
595    gint focus_width, focus_pad;
596    GtkAllocation child;
597    GtkRequisition req;
598 +  GtkRequisition child_req;
599    gboolean is_rtl = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
600 +  gboolean hildonlike;
601 +  gint arrow_width;
602 +  gint arrow_height;
603  
604    gtk_combo_box_check_appearance (combo_box);
605  
606 -  widget->allocation = *allocation;
607 -
608    gtk_widget_style_get (GTK_WIDGET (widget),
609                         "focus-line-width", &focus_width,
610                         "focus-padding", &focus_pad,
611 +                       "hildonlike", &hildonlike,
612 +                       "arrow-width", &arrow_width,
613 +                       "arrow-height", &arrow_height,
614                         NULL);
615  
616 +  /* HILDON: set height to fixed value */
617 +  if (hildonlike)
618 +    if (allocation->height > arrow_height)
619 +    {
620 +      allocation->y += (allocation->height - arrow_height) / 2;
621 +      allocation->height = arrow_height;
622 +    }
623 +
624 +  widget->allocation = *allocation;
625 +
626    if (!combo_box->priv->tree_view)
627      {
628        if (combo_box->priv->cell_view)
629 @@ -1909,7 +2199,16 @@
630                child.width = child.x;
631                child.x = allocation->x 
632                 + border_width + xthickness + focus_width + focus_pad;
633 -              child.width -= child.x;
634 +              child.width -= child.x + xthickness;
635 +            }
636 +            
637 +            if (hildonlike)
638 +            {
639 +                         gtk_widget_size_request(GTK_BIN(widget)->child, &child_req);
640 +                         child.y += (child.height - child_req.height) / 2;
641 +                               child.height = child_req.height;
642 +              gtk_widget_hide(combo_box->priv->separator);
643 +              gtk_widget_hide(combo_box->priv->arrow);
644              }
645  
646           child.width = MAX (1, child.width);
647 @@ -1928,6 +2227,11 @@
648            child.height = allocation->height;
649           child.width = MAX (1, child.width);
650           child.height = MAX (1, child.height);
651 +
652 +          /* HILDON quick fix */
653 +         if (hildonlike)
654 +           child.width = arrow_width;
655 +
656            gtk_widget_size_allocate (combo_box->priv->button, &child);
657  
658            if (is_rtl)
659 @@ -1938,6 +2242,13 @@
660            child.width = allocation->width - req.width;
661           child.width = MAX (1, child.width);
662           child.height = MAX (1, child.height);
663 +
664 +          if (hildonlike)
665 +          {
666 +            gtk_widget_size_request(GTK_BIN(widget)->child, &child_req);
667 +            child.y += (child.height - child_req.height) / 2;
668 +                       child.height = child_req.height;
669 +          }
670            gtk_widget_size_allocate (GTK_BIN (widget)->child, &child);
671          }
672      }
673 @@ -1990,6 +2301,11 @@
674                                    GTK_WIDGET (combo_box->priv->cell_view_frame)->style->ythickness);
675             }
676          }
677 +
678 +      gtk_widget_size_request(GTK_BIN(widget)->child, &child_req);
679 +
680 +      child.y += (child.height - child_req.height) / 2;
681 +      child.height = child_req.height;
682        
683        child.width = MAX (1, child.width);
684        child.height = MAX (1, child.height);
685 @@ -2036,6 +2352,8 @@
686      gtk_cell_view_set_displayed_row (GTK_CELL_VIEW (combo_box->priv->cell_view), NULL);
687  }
688  
689 +
690 +
691  static void
692  gtk_combo_box_forall (GtkContainer *container,
693                        gboolean      include_internals,
694 @@ -2057,6 +2375,46 @@
695  }
696  
697  static gboolean
698 +gtk_combo_box_focus_in (GtkWidget          *widget,
699 +                       GdkEventFocus      *event)
700 +{
701 +   g_return_val_if_fail( widget, FALSE );
702 +   
703 +   if ( !GTK_CONTAINER( widget )->focus_child )
704 +     {
705 +       gtk_combo_box_grab_focus ( GTK_WIDGET(widget) );
706 +       return TRUE;
707 +     }
708 +   return FALSE;  
709 +}
710 +
711 +static gint
712 +gtk_combo_box_focus (GtkWidget          *widget,
713 +                       GtkDirectionType dir)
714 +{
715 +   g_return_val_if_fail (widget, FALSE);
716 +   if (GTK_WIDGET_HAS_FOCUS(widget)||GTK_CONTAINER(widget)->focus_child)
717 +     return FALSE;
718 +
719 +   gtk_widget_grab_focus (widget);
720 +   return TRUE;
721 +}
722 +
723 +static void
724 +gtk_combo_box_child_focus_in (GtkWidget  * widget,
725 +                             GdkEventFocus *event)
726 +{
727 +   gtk_widget_event( widget, (GdkEvent*)event );
728 +}
729 +
730 +static void
731 +gtk_combo_box_child_focus_out (GtkWidget  * widget,
732 +                             GdkEventFocus *event)
733 +{
734 +   gtk_widget_event( widget, (GdkEvent*)event );
735 +}
736 +
737 +static gboolean
738  gtk_combo_box_expose_event (GtkWidget      *widget,
739                              GdkEventExpose *event)
740  {
741 @@ -2357,11 +2715,13 @@
742                            gboolean     add_children)
743  {
744    GtkWidget *menu;
745 +  gboolean hildonlike;
746 +
747 +  gtk_widget_style_get (GTK_WIDGET (combo_box), "hildonlike", &hildonlike, NULL);
748  
749    if (combo_box->priv->cell_view)
750      {
751        combo_box->priv->button = gtk_toggle_button_new ();
752 -
753        g_signal_connect (combo_box->priv->button, "toggled",
754                          G_CALLBACK (gtk_combo_box_button_toggled), combo_box);
755        g_signal_connect_after (combo_box->priv->button, 
756 @@ -2400,6 +2760,9 @@
757        gtk_widget_show_all (combo_box->priv->button);
758      }
759  
760 +  g_signal_connect_swapped (combo_box->priv->button, "focus_in_event", G_CALLBACK (gtk_combo_box_child_focus_in), combo_box);
761 +  g_signal_connect_swapped (combo_box->priv->button, "focus_out_event", G_CALLBACK (gtk_combo_box_child_focus_out), combo_box);
762 +
763    g_signal_connect (combo_box->priv->button, "button_press_event",
764                      G_CALLBACK (gtk_combo_box_menu_button_press),
765                      combo_box);
766 @@ -2749,6 +3112,9 @@
767  {
768    GtkComboBox *combo_box = GTK_COMBO_BOX (user_data);
769  
770 +  /* Hildon hack: sets the popup button sensitive if we have items in the list */
771 +  hildon_check_autodim(combo_box);
772 +
773    gtk_tree_row_reference_inserted (G_OBJECT (user_data), path);
774      
775    if (combo_box->priv->tree_view)
776 @@ -2783,7 +3149,10 @@
777    if (combo_box->priv->tree_view)
778      gtk_combo_box_list_popup_resize (combo_box);
779    else
780 -    gtk_combo_box_menu_row_deleted (model, path, user_data);  
781 +    gtk_combo_box_menu_row_deleted (model, path, user_data);        
782
783 +  /* Hildon hack: dim the popup button in case item count reaches 0 */
784 +  hildon_check_autodim(combo_box);
785  }
786  
787  static void
788 @@ -3458,10 +3827,46 @@
789    gboolean found;
790    GtkTreeIter iter;
791    GtkTreeIter new_iter;
792 +  gboolean hildonlike;
793 +  gint index = gtk_combo_box_get_active (combo_box);
794 +  gint new_index;
795 +  gint items = 0;
796  
797    if (combo_box->priv->model == NULL)
798      return FALSE;
799  
800 +  items = gtk_tree_model_iter_n_children (combo_box->priv->model, NULL);
801 +
802 +  gtk_widget_style_get (GTK_WIDGET (combo_box), "hildonlike",
803 +                       &hildonlike, NULL);
804 +
805 +  /* Hildon select key */
806 +  if (hildonlike)
807 +    {
808 +      if (event->keyval == GDK_KP_Enter || event->keyval == GDK_Return)
809 +        {
810 +          gtk_combo_box_popup (combo_box);
811 +          return TRUE;
812 +        }
813 +      else if (event->keyval == GDK_Left && items != 0)
814 +        {
815 +          new_index = (index == 0) ? items - 1 : index - 1;
816 +          gtk_combo_box_set_active (combo_box, new_index);
817 +          return TRUE;
818 +        }
819 +      else if (event->keyval == GDK_Right && items != 0)
820 +        {
821 +          new_index = (index == items - 1) ? 0 : index + 1;
822 +          gtk_combo_box_set_active (combo_box, new_index);
823 +          return TRUE;
824 +        }
825 +      else if ((event->keyval == GDK_Down || event->keyval == GDK_KP_Down)
826 +                || (event->keyval == GDK_Up || event->keyval == GDK_KP_Up))
827 +        {
828 +          return FALSE;
829 +        }
830 +    }
831 +
832    if ((event->keyval == GDK_Down || event->keyval == GDK_KP_Down) && 
833        state == GDK_MOD1_MASK)
834      {
835 @@ -3714,7 +4119,7 @@
836  
837    combo_box = GTK_COMBO_BOX (layout);
838  
839 -  g_object_ref (cell);
840 +  g_object_ref (G_OBJECT (cell));
841    gtk_object_sink (GTK_OBJECT (cell));
842  
843    info = g_new0 (ComboCellInfo, 1);
844 @@ -3771,7 +4176,7 @@
845  
846    combo_box = GTK_COMBO_BOX (layout);
847  
848 -  g_object_ref (cell);
849 +  g_object_ref (G_OBJECT (cell));
850    gtk_object_sink (GTK_OBJECT (cell));
851  
852    info = g_new0 (ComboCellInfo, 1);
853 @@ -3833,7 +4238,7 @@
854       ComboCellInfo *info = (ComboCellInfo *)i->data;
855  
856        gtk_combo_box_cell_layout_clear_attributes (layout, info->cell);
857 -      g_object_unref (info->cell);
858 +      g_object_unref (G_OBJECT (info->cell));
859        g_free (info);
860        i->data = NULL;
861      }
862 @@ -3922,7 +4327,7 @@
863    
864    if (GTK_IS_MENU_ITEM (parent) && 
865        gtk_menu_item_get_submenu (GTK_MENU_ITEM (parent)))
866 -    g_object_set (cell, "sensitive", TRUE, NULL);
867 +    g_object_set (G_OBJECT (cell), "sensitive", TRUE, NULL);
868  }
869  
870  
871 @@ -4137,7 +4542,7 @@
872  GtkWidget *
873  gtk_combo_box_new (void)
874  {
875 -  return g_object_new (GTK_TYPE_COMBO_BOX, NULL);
876 +  return GTK_WIDGET (g_object_new (GTK_TYPE_COMBO_BOX, NULL));
877  }
878  
879  /**
880 @@ -4157,7 +4562,9 @@
881  
882    g_return_val_if_fail (GTK_IS_TREE_MODEL (model), NULL);
883  
884 -  combo_box = g_object_new (GTK_TYPE_COMBO_BOX, "model", model, NULL);
885 +  combo_box = GTK_COMBO_BOX (g_object_new (GTK_TYPE_COMBO_BOX,
886 +                                           "model", model,
887 +                                           NULL));
888  
889    return GTK_WIDGET (combo_box);
890  }
891 @@ -4512,6 +4919,7 @@
892    if (!model)
893      {
894        gtk_combo_box_unset_model (combo_box);
895 +      hildon_check_autodim(combo_box);
896        return;
897      }
898  
899 @@ -4524,7 +4932,7 @@
900      gtk_combo_box_unset_model (combo_box);
901  
902    combo_box->priv->model = model;
903 -  g_object_ref (combo_box->priv->model);
904 +  g_object_ref (G_OBJECT (combo_box->priv->model));
905  
906    combo_box->priv->inserted_id =
907      g_signal_connect (combo_box->priv->model, "row_inserted",
908 @@ -4561,6 +4969,8 @@
909    if (combo_box->priv->cell_view)
910      gtk_cell_view_set_model (GTK_CELL_VIEW (combo_box->priv->cell_view),
911                               combo_box->priv->model);
912 +
913 +  hildon_check_autodim(combo_box);
914  }
915  
916  /**
917 @@ -5140,3 +5550,33 @@
918    
919    return combo->priv->focus_on_click;
920  }
921 +/* Hildon addition:
922 + * This is added, because we need to be able grab focus for our widget.
923 + * Focus grabbing can happen it two ways: If we are using combobox entry
924 + * we grab entry widget focus, otherwise togglebutton focus
925 + */
926 +static void    gtk_combo_box_grab_focus         (GtkWidget         *focus_widget)
927 +{
928 +  GtkComboBox *combo_box;
929 +  GtkComboBoxEntry *combo_entry;
930 +  gboolean hildonlike;
931 +
932 +  combo_box = GTK_COMBO_BOX (focus_widget);
933 +  
934 +  gtk_widget_style_get (focus_widget, "hildonlike",
935 +                       &hildonlike, NULL);
936 +
937 +  if (hildonlike)
938 +    {
939 +      /* Are we in entry mode ? */
940 +      if ( GTK_IS_COMBO_BOX_ENTRY(combo_box))
941 +        {
942 +          combo_entry = GTK_COMBO_BOX_ENTRY (combo_box);
943 +          gtk_grab_combo_box_entry_focus (combo_entry);
944 +        }
945 +      else
946 +        {
947 +          gtk_widget_grab_focus (combo_box->priv->button);
948 +        }
949 +    }
950 +}