--- gtk+-2.6.4/gtk/gtkcombobox.c	2005-02-25 21:11:08.000000000 +0200
+++ gtk+-2.6.4/gtk/gtkcombobox.c	2005-04-06 16:19:36.406003808 +0300
@@ -17,6 +17,10 @@
  * Boston, MA 02111-1307, USA.
  */
 
+/*
+ * Modified for Nokia Oyj during 2002-2004. 
+ */
+
 #include <config.h>
 #include "gtkalias.h"
 #include "gtkcombobox.h"
@@ -39,6 +43,8 @@
 #include "gtktreeselection.h"
 #include "gtkvseparator.h"
 #include "gtkwindow.h"
+#include "gtkcomboboxentry.h"
+#include "gtktoolbar.h"
 
 #include <gdk/gdkkeysyms.h>
 
@@ -52,6 +58,13 @@
 
 #include "gtktreeprivate.h"
 
+#define HILDON_MAX_WIDTH 406
+#define HILDON_MAX_HEIGHT 305
+#define HILDON_MAX_ITEMS 8
+/* this is also defined in gtkmenu.c and should be replaced with
+  a style property */
+#define MENU_SCROLL_ARROW_HEIGHT 20 
+
 /* WELCOME, to THE house of evil code */
 
 typedef struct _ComboCellInfo ComboCellInfo;
@@ -119,6 +132,9 @@
   GtkTreeViewRowSeparatorFunc row_separator_func;
   gpointer                    row_separator_data;
   GtkDestroyNotify            row_separator_destroy;
+
+  /* Hildon hack: state of our style property */
+  gboolean autodimmed_button;
 };
 
 /* While debugging this evil code, I have learned that
@@ -201,6 +217,7 @@
 
 #define BONUS_PADDING 4
 #define SCROLL_TIME  100
+#define HILDON_PADDING 25
 
 /* common */
 static void     gtk_combo_box_class_init           (GtkComboBoxClass *klass);
@@ -273,6 +290,14 @@
                                                     gboolean          include_internals,
                                                     GtkCallback       callback,
                                                     gpointer          callback_data);
+static gboolean gtk_combo_box_focus_in             (GtkWidget        *widget,
+                                                    GdkEventFocus    *event);
+static gint gtk_combo_box_focus             (GtkWidget        *widget,
+                                                    GtkDirectionType dir);
+static void gtk_combo_box_child_focus_in            (GtkWidget        *widget,
+                                                    GdkEventFocus    *event);
+static void gtk_combo_box_child_focus_out            (GtkWidget        *widget,
+                                                    GdkEventFocus    *event);
 static gboolean gtk_combo_box_expose_event         (GtkWidget        *widget,
                                                     GdkEventExpose   *event);
 static gboolean gtk_combo_box_scroll_event         (GtkWidget        *widget,
@@ -285,6 +310,12 @@
 
 static void     gtk_combo_box_check_appearance     (GtkComboBox      *combo_box);
 
+/* <Hildon addition> */
+extern void     gtk_grab_combo_box_entry_focus   (GtkComboBoxEntry *entry_box);
+
+static void    gtk_combo_box_grab_focus         (GtkWidget         *focus_widget);
+/* </hildon addition> */
+
 /* listening to the model */
 static void     gtk_combo_box_model_row_inserted   (GtkTreeModel     *model,
 						    GtkTreePath      *path,
@@ -424,6 +455,9 @@
 static void gtk_combo_box_start_editing (GtkCellEditable *cell_editable,
 					 GdkEvent        *event);
 
+static void gtk_combo_box_menu_position_above (GtkMenu  *menu, gint     *x,
+					       gint     *y, gboolean *push_in,
+					       gpointer  user_data);
 
 GType
 gtk_combo_box_get_type (void)
@@ -479,6 +513,25 @@
   return combo_box_type;
 }
 
+/* Hildon addition: Check if the button needs to be dimmed */
+static void hildon_check_autodim(GtkComboBox *combo_box)
+{
+  GtkWidget *widget;
+  GtkTreeModel *model;
+  GtkTreeIter iter;
+
+  widget = combo_box->priv->button;
+  model = combo_box->priv->model;
+
+  if (combo_box->priv->autodimmed_button && widget != NULL)
+    {
+      if (model && gtk_tree_model_get_iter_first(model, &iter))
+        gtk_widget_set_sensitive(widget, TRUE);
+      else 
+        gtk_widget_set_sensitive(widget, FALSE);
+    }
+}
+
 /* common */
 static void
 gtk_combo_box_class_init (GtkComboBoxClass *klass)
@@ -504,6 +557,11 @@
   widget_class->mnemonic_activate = gtk_combo_box_mnemonic_activate;
   widget_class->style_set = gtk_combo_box_style_set;
   widget_class->state_changed = gtk_combo_box_state_changed;
+  
+  /* Hildon addition */
+  widget_class->grab_focus = gtk_combo_box_grab_focus;
+  widget_class->focus_in_event = gtk_combo_box_focus_in;
+  widget_class->focus = gtk_combo_box_focus;
 
   gtk_object_class = (GtkObjectClass *)klass;
   gtk_object_class->destroy = gtk_combo_box_destroy;
@@ -687,6 +745,41 @@
                                                                  FALSE,
                                                                  G_PARAM_READABLE));
 
+  gtk_widget_class_install_style_property (widget_class,
+                                  g_param_spec_boolean ("hildonlike",
+                                  _("Size request"),
+				  _("Size allocate"),
+                                  FALSE,
+                                  G_PARAM_READABLE));
+
+  gtk_widget_class_install_style_property (widget_class,
+                                          g_param_spec_int ("arrow-height",
+							      P_("Arrow height for option menu"),
+							      P_("Sets arrow height"),
+							      0,
+							      G_MAXINT,
+							      28,
+							      G_PARAM_READWRITE));
+
+  gtk_widget_class_install_style_property (widget_class,
+                                          g_param_spec_int ("arrow-width",
+							      P_("Arrow width for option menu"),
+							      P_("Sets arrow width"),
+							      0,
+							      G_MAXINT,
+							      26,
+							      G_PARAM_READWRITE));
+
+
+  /* Hildon hack: style property for enabling the autodimming hack */
+  gtk_widget_class_install_style_property (
+    widget_class,
+    g_param_spec_boolean ("autodimmed_button",
+    _("Autodimmed button"),
+    _("Automatically dims the button if the list is empty"),
+    FALSE,
+    G_PARAM_READABLE));
+
   g_type_class_add_private (object_class, sizeof (GtkComboBoxPrivate));
 }
 
@@ -731,6 +824,11 @@
   combo_box->priv->editing_canceled = FALSE;
   combo_box->priv->auto_scroll = FALSE;
   combo_box->priv->focus_on_click = TRUE;
+
+  /* Hildon hack: default value for our style property if it is queried before
+   *              the style is set */
+  combo_box->priv->autodimmed_button = FALSE;
+  GTK_WIDGET_SET_FLAGS ( combo_box, GTK_CAN_FOCUS );
 }
 
 static void
@@ -911,7 +1009,19 @@
 {
   GtkComboBox *combo_box = GTK_COMBO_BOX (widget);
 
+  /* Hildon hack: read the state of our style property */
+  gtk_widget_style_get (GTK_WIDGET(combo_box),
+    "autodimmed_button", &(combo_box->priv->autodimmed_button), NULL);
+  
   gtk_combo_box_check_appearance (combo_box);
+  
+  /* Hildon hack: handle the dimmed state of the button in regards whether
+   *              the list is empty or not. This has to be done here because
+   *              in the callback functions of GtkTreeModel the button widget
+   *              may have not yet been set. However, we repeat this stuff in
+   *              those functions, because later the button will be set and
+   *              we want to update our state. */
+  hildon_check_autodim(combo_box);
 
   if (combo_box->priv->tree_view && combo_box->priv->cell_view)
     gtk_cell_view_set_background_color (GTK_CELL_VIEW (combo_box->priv->cell_view), 
@@ -922,10 +1032,17 @@
 gtk_combo_box_button_toggled (GtkWidget *widget,
                               gpointer   data)
 {
+  gboolean hildonlike;
   GtkComboBox *combo_box = GTK_COMBO_BOX (data);
+  
+  gtk_widget_style_get (GTK_WIDGET (combo_box), "hildonlike", &hildonlike, NULL);
 
   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
     {
+       if (hildonlike) {
+	  gtk_combo_box_grab_focus(GTK_WIDGET(combo_box));
+       }
+      
       if (!combo_box->priv->popup_in_progress)
         gtk_combo_box_popup (combo_box);
     }
@@ -1103,7 +1220,7 @@
     {
       gtk_container_remove (GTK_CONTAINER (combo_box->priv->popup_frame),
                             combo_box->priv->popup_widget);
-      g_object_unref (combo_box->priv->popup_widget);
+      g_object_unref (G_OBJECT (combo_box->priv->popup_widget));
       combo_box->priv->popup_widget = NULL;
     }
 
@@ -1175,7 +1292,7 @@
                          popup);
 
       gtk_widget_show (popup);
-      g_object_ref (popup);
+      g_object_ref (G_OBJECT (popup));
       combo_box->priv->popup_widget = popup;
     }
 }
@@ -1250,9 +1367,13 @@
   GtkRequisition requisition;
   GList *children;
   gint screen_width;
+  gint screen_height;
   gint menu_xpos;
   gint menu_ypos;
-  gint menu_width;
+  gint menu_width, menu_height;
+  gint counter = 0;
+  gint scroll_offset = 0;
+  gint max_items = 0;
 
   g_return_if_fail (GTK_IS_COMBO_BOX (user_data));
   
@@ -1261,6 +1382,7 @@
 
   gtk_widget_get_child_requisition (GTK_WIDGET (menu), &requisition);
   menu_width = requisition.width;
+  menu_height = requisition.height;
 
   active = gtk_menu_get_active (GTK_MENU (combo_box->priv->popup_widget));
   gdk_window_get_origin (widget->window, &menu_xpos, &menu_ypos);
@@ -1275,6 +1397,11 @@
     }
 
   children = GTK_MENU_SHELL (combo_box->priv->popup_widget)->children;
+  child = children->data;
+  gtk_widget_get_child_requisition (child, &requisition);
+  max_items = (HILDON_MAX_HEIGHT-2*MENU_SCROLL_ARROW_HEIGHT)/requisition.height;
+  max_items -= 1;
+  
   while (children)
     {
       child = children->data;
@@ -1284,27 +1411,119 @@
 
       if (GTK_WIDGET_VISIBLE (child))
 	{
-	  gtk_widget_get_child_requisition (child, &requisition);
-	  menu_ypos -= requisition.height;
+          if (counter < max_items - 2)
+              menu_ypos -= requisition.height;
+          if (counter > max_items - 3)
+              scroll_offset += requisition.height;        
 	}
-
+      
+      counter++;
       children = children->next;
     }
+  gtk_widget_get_child_requisition (GTK_WIDGET(menu), &requisition);
 
+  if ( requisition.height >= HILDON_MAX_HEIGHT )
+      menu_ypos -= MENU_SCROLL_ARROW_HEIGHT;
+  
   if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
     menu_xpos = menu_xpos + widget->allocation.width - menu_width;
 
+  {
+    gint menu_xpad, menu_ypad;
+    gtk_widget_style_get (GTK_WIDGET (menu),
+    "horizontal-padding", &menu_xpad,
+    "vertical-padding", &menu_ypad,
+    NULL);
+    menu_xpos -= menu_xpad - 3;
+    menu_ypos -= menu_ypad - 1;
+  }
+
   /* Clamp the position on screen */
   screen_width = gdk_screen_get_width (gtk_widget_get_screen (widget));
+  screen_height = gdk_screen_get_height (gtk_widget_get_screen (widget));
   
   if (menu_xpos < 0)
     menu_xpos = 0;
   else if ((menu_xpos + menu_width) > screen_width)
     menu_xpos -= ((menu_xpos + menu_width) - screen_width);
 
+  if (menu_ypos + menu_height > screen_height)
+  {
+      menu_ypos = screen_height - menu_height;
+  }
+  if (menu_ypos < 0)
+  {
+      menu_ypos = 0;
+  }
+
+  GTK_MENU(combo_box->priv->popup_widget)->scroll_offset = scroll_offset;
+  
   *x = menu_xpos;
   *y = menu_ypos;
 
+  *push_in = FALSE;
+}
+
+static void 
+gtk_combo_box_menu_position_above (GtkMenu  *menu,
+				   gint     *x,
+				   gint     *y,
+				   gboolean *push_in,
+				   gpointer  user_data)
+{
+  /* 
+   * This function positiones the menu above widgets.
+   * This is a modified version of the position function 
+   * gtk_combo_box_position_over. 
+   * NB: This is only used when gtkcombobox is in toolbar!
+   */
+
+  GtkWidget *child;
+  GtkRequisition requisition;
+  GList *children;
+  gint screen_width;
+  gint menu_xpos;
+  gint menu_ypos;
+  gint gx,gy;
+  gint menu_width;
+  GtkWidget *widget;
+
+  widget = GTK_WIDGET(user_data);
+
+  gtk_widget_get_child_requisition (GTK_WIDGET (menu), &requisition);
+  menu_width = requisition.width;
+
+  gdk_window_get_position(GDK_WINDOW(widget->window), &gx, &gy);
+  gtk_widget_translate_coordinates (widget, gtk_widget_get_toplevel(widget),
+                                    gx, gy, &menu_xpos, &menu_ypos);
+
+  menu_ypos -= GTK_WIDGET(menu)->style->ythickness * 2;
+  menu_ypos -= GTK_WIDGET(widget)->style->ythickness * 2;
+
+  menu_ypos -= widget->allocation.height;
+
+  children = GTK_MENU_SHELL (menu)->children;
+  while (children) {
+    child = children->data;    
+    if (GTK_WIDGET_VISIBLE (child)){      
+      gtk_widget_get_child_requisition (child, &requisition);
+      menu_ypos -= requisition.height;
+    }
+    children = children->next;
+  }
+
+  if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
+    menu_xpos = menu_xpos + widget->allocation.width - menu_width;
+
+  screen_width = gdk_screen_get_width (gtk_widget_get_screen (widget));
+  
+  if (menu_xpos < 0)
+    menu_xpos = 0;
+  else if ((menu_xpos + menu_width) > screen_width)
+    menu_xpos -= ((menu_xpos + menu_width) - screen_width);
+
+  *x = menu_xpos;
+  *y = menu_ypos;
   *push_in = TRUE;
 }
 
@@ -1318,21 +1537,44 @@
   GtkComboBox *combo_box;
   GtkWidget *menu_item;
 
+  gboolean hildonlike;
+
   combo_box = GTK_COMBO_BOX (user_data);
 
-  if (combo_box->priv->wrap_width > 0 || combo_box->priv->cell_view == NULL)	
-    gtk_combo_box_menu_position_below (menu, x, y, push_in, user_data);
-  else
+  gtk_widget_style_get (GTK_WIDGET (combo_box), "hildonlike", &hildonlike, NULL);
+
+  if (!(combo_box->priv->wrap_width > 0 || combo_box->priv->cell_view == NULL))
     {
       /* FIXME handle nested menus better */
       menu_item = gtk_menu_get_active (GTK_MENU (combo_box->priv->popup_widget));
       if (menu_item)
 	gtk_menu_shell_select_item (GTK_MENU_SHELL (combo_box->priv->popup_widget), 
 				    menu_item);
+    }
 
-      gtk_combo_box_menu_position_over (menu, x, y, push_in, user_data);
+  if (hildonlike) 
+    {
+      /* HILDON: we check if combobox is in a toolbar */
+      gboolean in_toolbar = gtk_widget_get_ancestor(GTK_WIDGET(combo_box), GTK_TYPE_TOOLBAR) != NULL;
+      if (in_toolbar)
+	{
+	  /*due to limits in combo's sizes we use position_over here also*/
+          gtk_combo_box_menu_position_over (menu, x, y, push_in, user_data);	
+	  return;
+	}
     }
 
+  if (combo_box->priv->wrap_width > 0 || combo_box->priv->cell_view == NULL)	
+/*
+ * Changed because we always want the combo box position to be over
+ * the combo box, unless it's in toolbar.
+ *
+    gtk_combo_box_menu_position_below (menu, x, y, push_in, user_data);
+*/
+    gtk_combo_box_menu_position_over (menu, x, y, push_in, user_data);	      
+  else
+    gtk_combo_box_menu_position_over (menu, x, y, push_in, user_data);	      
+
 }
 
 static void
@@ -1430,7 +1672,7 @@
   list = cells;
   while (list)
     {
-      g_object_get (list->data, "sensitive", &sensitive, NULL);
+      g_object_get (G_OBJECT (list->data), "sensitive", &sensitive, NULL);
       
       if (sensitive)
 	break;
@@ -1469,7 +1711,7 @@
   list = cells;
   while (list)
     {
-      g_object_get (list->data, "sensitive", &sensitive, NULL);
+      g_object_get (G_OBJECT (list->data), "sensitive", &sensitive, NULL);
       
       if (sensitive)
 	break;
@@ -1516,8 +1758,8 @@
 	  if (menu != combo_box->priv->popup_widget && child == children)
 	    {
 	      separator = GTK_WIDGET (child->next->data);
-	      g_object_set (item, "visible", sensitive, NULL);
-	      g_object_set (separator, "visible", sensitive, NULL);
+	      g_object_set (G_OBJECT (item), "visible", sensitive, NULL);
+	      g_object_set (G_OBJECT (separator), "visible", sensitive, NULL);
 	    }
 	  else
 	    gtk_widget_set_sensitive (item, sensitive);
@@ -1543,16 +1785,19 @@
   if (gtk_tree_row_reference_valid (combo_box->priv->active_row))
     {
       path = gtk_tree_row_reference_get_path (combo_box->priv->active_row);
-      active_item = gtk_tree_path_get_indices (path)[0];
-      gtk_tree_path_free (path);
-      
-      if (combo_box->priv->add_tearoffs)
-	active_item++;
+      if (path)
+	{
+	  active_item = gtk_tree_path_get_indices (path)[0];
+	  gtk_tree_path_free (path);
+
+	  if (combo_box->priv->add_tearoffs)
+	    active_item++;
+	}
     }
 
   /* FIXME handle nested menus better */
-  gtk_menu_set_active (GTK_MENU (combo_box->priv->popup_widget), active_item);
-  
+  gtk_menu_set_active (GTK_MENU (combo_box->priv->popup_widget), active_item);  
+     
   if (combo_box->priv->wrap_width == 0)
     {
       width = GTK_WIDGET (combo_box)->allocation.width;
@@ -1684,6 +1929,7 @@
 {
   gint padding;
   GtkRequisition req;
+  gboolean hildonlike;
 
   if (combo_box->priv->cell_view)
     gtk_widget_style_get (combo_box->priv->cell_view,
@@ -1691,9 +1937,17 @@
                           NULL);
   else
     padding = 0;
+  
+   gtk_widget_style_get (GTK_WIDGET (combo_box), "hildonlike", &hildonlike,
+			 NULL);
 
   /* add some pixels for good measure */
-  padding += BONUS_PADDING;
+  /* Hildon: we need more padding because our theming
+   * Not elegent way to do it anyway ... */
+  if (hildonlike)
+    padding += HILDON_PADDING;
+  else
+    padding += BONUS_PADDING;
 
   if (combo_box->priv->cell_view)
     gtk_cell_view_get_size_of_row (GTK_CELL_VIEW (combo_box->priv->cell_view),
@@ -1709,6 +1963,7 @@
 {
   GtkTreeIter iter;
   GtkTreePath *path;
+  gboolean hildonlike;
 
   if (!combo_box->priv->model ||
       !gtk_tree_model_get_iter_first (combo_box->priv->model, &iter))
@@ -1717,6 +1972,7 @@
   combo_box->priv->width = 0;
 
   path = gtk_tree_path_new_from_indices (0, -1);
+  gtk_widget_style_get (GTK_WIDGET (combo_box), "hildonlike", &hildonlike, NULL);
 
   do
     {
@@ -1727,8 +1983,11 @@
                                        path, &req);
       else
         req.width = 0;
+  /* Hildon: we need more padding because our theming
+   * Not elegent way to do it anyway ... */
 
-      combo_box->priv->width = MAX (combo_box->priv->width, req.width);
+      combo_box->priv->width = MAX (combo_box->priv->width,
+                                    req.width + (hildonlike == 1) ? HILDON_PADDING : 0 );
 
       gtk_tree_path_next (path);
     }
@@ -1744,10 +2003,19 @@
   gint width, height;
   gint focus_width, focus_pad;
   GtkRequisition bin_req;
+  gboolean hildonlike;
+  gint arrow_width;
+  gint arrow_height;
 
   GtkComboBox *combo_box = GTK_COMBO_BOX (widget);
 
   gtk_combo_box_check_appearance (combo_box);
+  
+  /* get hildonlike style property */
+  gtk_widget_style_get (widget, "hildonlike",
+		        &hildonlike, "arrow-width",
+			&arrow_width, "arrow-height",
+			&arrow_height, NULL);
 
   /* common */
   gtk_widget_size_request (GTK_BIN (widget)->child, &bin_req);
@@ -1829,6 +2097,13 @@
       requisition->height = MAX (requisition->height, button_req.height);
       requisition->width += button_req.width;
     }
+
+  requisition->width = MIN (requisition->width, HILDON_MAX_WIDTH);
+  
+  /* HILDON quick fix: height forced to be 28px as specified by Hildon specs. */
+  if (hildonlike)
+    if (requisition->height > arrow_height)
+      requisition->height = arrow_height;
 }
 
 static void
@@ -1839,17 +2114,32 @@
   gint focus_width, focus_pad;
   GtkAllocation child;
   GtkRequisition req;
+  GtkRequisition child_req;
   gboolean is_rtl = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
+  gboolean hildonlike;
+  gint arrow_width;
+  gint arrow_height;
 
   gtk_combo_box_check_appearance (combo_box);
 
-  widget->allocation = *allocation;
-
   gtk_widget_style_get (GTK_WIDGET (widget),
 			"focus-line-width", &focus_width,
 			"focus-padding", &focus_pad,
+			"hildonlike", &hildonlike,
+			"arrow-width", &arrow_width,
+			"arrow-height", &arrow_height,
 			NULL);
 
+  /* HILDON: set height to fixed value */
+  if (hildonlike)
+    if (allocation->height > arrow_height)
+    {
+      allocation->y += (allocation->height - arrow_height) / 2;
+      allocation->height = arrow_height;
+    }
+
+  widget->allocation = *allocation;
+
   if (!combo_box->priv->tree_view)
     {
       if (combo_box->priv->cell_view)
@@ -1909,7 +2199,16 @@
               child.width = child.x;
               child.x = allocation->x 
 		+ border_width + xthickness + focus_width + focus_pad;
-              child.width -= child.x;
+              child.width -= child.x + xthickness;
+            }
+            
+            if (hildonlike)
+            {
+		          gtk_widget_size_request(GTK_BIN(widget)->child, &child_req);
+		          child.y += (child.height - child_req.height) / 2;
+			        child.height = child_req.height;
+              gtk_widget_hide(combo_box->priv->separator);
+              gtk_widget_hide(combo_box->priv->arrow);
             }
 
 	  child.width = MAX (1, child.width);
@@ -1928,6 +2227,11 @@
           child.height = allocation->height;
 	  child.width = MAX (1, child.width);
 	  child.height = MAX (1, child.height);
+
+          /* HILDON quick fix */
+	  if (hildonlike)
+	    child.width = arrow_width;
+
           gtk_widget_size_allocate (combo_box->priv->button, &child);
 
           if (is_rtl)
@@ -1938,6 +2242,13 @@
           child.width = allocation->width - req.width;
 	  child.width = MAX (1, child.width);
 	  child.height = MAX (1, child.height);
+
+          if (hildonlike)
+          {
+            gtk_widget_size_request(GTK_BIN(widget)->child, &child_req);
+            child.y += (child.height - child_req.height) / 2;
+			child.height = child_req.height;
+          }
           gtk_widget_size_allocate (GTK_BIN (widget)->child, &child);
         }
     }
@@ -1990,6 +2301,11 @@
 				   GTK_WIDGET (combo_box->priv->cell_view_frame)->style->ythickness);
 	    }
         }
+
+      gtk_widget_size_request(GTK_BIN(widget)->child, &child_req);
+
+      child.y += (child.height - child_req.height) / 2;
+      child.height = child_req.height;
       
       child.width = MAX (1, child.width);
       child.height = MAX (1, child.height);
@@ -2036,6 +2352,8 @@
     gtk_cell_view_set_displayed_row (GTK_CELL_VIEW (combo_box->priv->cell_view), NULL);
 }
 
+
+
 static void
 gtk_combo_box_forall (GtkContainer *container,
                       gboolean      include_internals,
@@ -2057,6 +2375,46 @@
 }
 
 static gboolean
+gtk_combo_box_focus_in (GtkWidget          *widget,
+			GdkEventFocus      *event)
+{
+   g_return_val_if_fail( widget, FALSE );
+   
+   if ( !GTK_CONTAINER( widget )->focus_child )
+     {
+	gtk_combo_box_grab_focus ( GTK_WIDGET(widget) );
+	return TRUE;
+     }
+   return FALSE;  
+}
+
+static gint
+gtk_combo_box_focus (GtkWidget          *widget,
+			GtkDirectionType dir)
+{
+   g_return_val_if_fail (widget, FALSE);
+   if (GTK_WIDGET_HAS_FOCUS(widget)||GTK_CONTAINER(widget)->focus_child)
+     return FALSE;
+
+   gtk_widget_grab_focus (widget);
+   return TRUE;
+}
+
+static void
+gtk_combo_box_child_focus_in (GtkWidget  * widget,
+			      GdkEventFocus *event)
+{
+   gtk_widget_event( widget, (GdkEvent*)event );
+}
+
+static void
+gtk_combo_box_child_focus_out (GtkWidget  * widget,
+			      GdkEventFocus *event)
+{
+   gtk_widget_event( widget, (GdkEvent*)event );
+}
+
+static gboolean
 gtk_combo_box_expose_event (GtkWidget      *widget,
                             GdkEventExpose *event)
 {
@@ -2357,11 +2715,13 @@
                           gboolean     add_children)
 {
   GtkWidget *menu;
+  gboolean hildonlike;
+
+  gtk_widget_style_get (GTK_WIDGET (combo_box), "hildonlike", &hildonlike, NULL);
 
   if (combo_box->priv->cell_view)
     {
       combo_box->priv->button = gtk_toggle_button_new ();
-
       g_signal_connect (combo_box->priv->button, "toggled",
                         G_CALLBACK (gtk_combo_box_button_toggled), combo_box);
       g_signal_connect_after (combo_box->priv->button, 
@@ -2400,6 +2760,9 @@
       gtk_widget_show_all (combo_box->priv->button);
     }
 
+  g_signal_connect_swapped (combo_box->priv->button, "focus_in_event", G_CALLBACK (gtk_combo_box_child_focus_in), combo_box);
+  g_signal_connect_swapped (combo_box->priv->button, "focus_out_event", G_CALLBACK (gtk_combo_box_child_focus_out), combo_box);
+
   g_signal_connect (combo_box->priv->button, "button_press_event",
                     G_CALLBACK (gtk_combo_box_menu_button_press),
                     combo_box);
@@ -2749,6 +3112,9 @@
 {
   GtkComboBox *combo_box = GTK_COMBO_BOX (user_data);
 
+  /* Hildon hack: sets the popup button sensitive if we have items in the list */
+  hildon_check_autodim(combo_box);
+
   gtk_tree_row_reference_inserted (G_OBJECT (user_data), path);
     
   if (combo_box->priv->tree_view)
@@ -2783,7 +3149,10 @@
   if (combo_box->priv->tree_view)
     gtk_combo_box_list_popup_resize (combo_box);
   else
-    gtk_combo_box_menu_row_deleted (model, path, user_data);  
+    gtk_combo_box_menu_row_deleted (model, path, user_data);        
+ 
+  /* Hildon hack: dim the popup button in case item count reaches 0 */
+  hildon_check_autodim(combo_box);
 }
 
 static void
@@ -3458,10 +3827,46 @@
   gboolean found;
   GtkTreeIter iter;
   GtkTreeIter new_iter;
+  gboolean hildonlike;
+  gint index = gtk_combo_box_get_active (combo_box);
+  gint new_index;
+  gint items = 0;
 
   if (combo_box->priv->model == NULL)
     return FALSE;
 
+  items = gtk_tree_model_iter_n_children (combo_box->priv->model, NULL);
+
+  gtk_widget_style_get (GTK_WIDGET (combo_box), "hildonlike",
+			&hildonlike, NULL);
+
+  /* Hildon select key */
+  if (hildonlike)
+    {
+      if (event->keyval == GDK_KP_Enter || event->keyval == GDK_Return)
+        {
+          gtk_combo_box_popup (combo_box);
+          return TRUE;
+        }
+      else if (event->keyval == GDK_Left && items != 0)
+        {
+          new_index = (index == 0) ? items - 1 : index - 1;
+          gtk_combo_box_set_active (combo_box, new_index);
+          return TRUE;
+        }
+      else if (event->keyval == GDK_Right && items != 0)
+        {
+          new_index = (index == items - 1) ? 0 : index + 1;
+          gtk_combo_box_set_active (combo_box, new_index);
+          return TRUE;
+        }
+      else if ((event->keyval == GDK_Down || event->keyval == GDK_KP_Down)
+                || (event->keyval == GDK_Up || event->keyval == GDK_KP_Up))
+        {
+          return FALSE;
+        }
+    }
+
   if ((event->keyval == GDK_Down || event->keyval == GDK_KP_Down) && 
       state == GDK_MOD1_MASK)
     {
@@ -3714,7 +4119,7 @@
 
   combo_box = GTK_COMBO_BOX (layout);
 
-  g_object_ref (cell);
+  g_object_ref (G_OBJECT (cell));
   gtk_object_sink (GTK_OBJECT (cell));
 
   info = g_new0 (ComboCellInfo, 1);
@@ -3771,7 +4176,7 @@
 
   combo_box = GTK_COMBO_BOX (layout);
 
-  g_object_ref (cell);
+  g_object_ref (G_OBJECT (cell));
   gtk_object_sink (GTK_OBJECT (cell));
 
   info = g_new0 (ComboCellInfo, 1);
@@ -3833,7 +4238,7 @@
      ComboCellInfo *info = (ComboCellInfo *)i->data;
 
       gtk_combo_box_cell_layout_clear_attributes (layout, info->cell);
-      g_object_unref (info->cell);
+      g_object_unref (G_OBJECT (info->cell));
       g_free (info);
       i->data = NULL;
     }
@@ -3922,7 +4327,7 @@
   
   if (GTK_IS_MENU_ITEM (parent) && 
       gtk_menu_item_get_submenu (GTK_MENU_ITEM (parent)))
-    g_object_set (cell, "sensitive", TRUE, NULL);
+    g_object_set (G_OBJECT (cell), "sensitive", TRUE, NULL);
 }
 
 
@@ -4137,7 +4542,7 @@
 GtkWidget *
 gtk_combo_box_new (void)
 {
-  return g_object_new (GTK_TYPE_COMBO_BOX, NULL);
+  return GTK_WIDGET (g_object_new (GTK_TYPE_COMBO_BOX, NULL));
 }
 
 /**
@@ -4157,7 +4562,9 @@
 
   g_return_val_if_fail (GTK_IS_TREE_MODEL (model), NULL);
 
-  combo_box = g_object_new (GTK_TYPE_COMBO_BOX, "model", model, NULL);
+  combo_box = GTK_COMBO_BOX (g_object_new (GTK_TYPE_COMBO_BOX,
+                                           "model", model,
+                                           NULL));
 
   return GTK_WIDGET (combo_box);
 }
@@ -4512,6 +4919,7 @@
   if (!model)
     {
       gtk_combo_box_unset_model (combo_box);
+      hildon_check_autodim(combo_box);
       return;
     }
 
@@ -4524,7 +4932,7 @@
     gtk_combo_box_unset_model (combo_box);
 
   combo_box->priv->model = model;
-  g_object_ref (combo_box->priv->model);
+  g_object_ref (G_OBJECT (combo_box->priv->model));
 
   combo_box->priv->inserted_id =
     g_signal_connect (combo_box->priv->model, "row_inserted",
@@ -4561,6 +4969,8 @@
   if (combo_box->priv->cell_view)
     gtk_cell_view_set_model (GTK_CELL_VIEW (combo_box->priv->cell_view),
                              combo_box->priv->model);
+
+  hildon_check_autodim(combo_box);
 }
 
 /**
@@ -5140,3 +5550,33 @@
   
   return combo->priv->focus_on_click;
 }
+/* Hildon addition:
+ * This is added, because we need to be able grab focus for our widget.
+ * Focus grabbing can happen it two ways: If we are using combobox entry
+ * we grab entry widget focus, otherwise togglebutton focus
+ */
+static void	gtk_combo_box_grab_focus	 (GtkWidget         *focus_widget)
+{
+  GtkComboBox *combo_box;
+  GtkComboBoxEntry *combo_entry;
+  gboolean hildonlike;
+
+  combo_box = GTK_COMBO_BOX (focus_widget);
+  
+  gtk_widget_style_get (focus_widget, "hildonlike",
+			&hildonlike, NULL);
+
+  if (hildonlike)
+    {
+      /* Are we in entry mode ? */
+      if ( GTK_IS_COMBO_BOX_ENTRY(combo_box))
+        {
+	   combo_entry = GTK_COMBO_BOX_ENTRY (combo_box);
+	   gtk_grab_combo_box_entry_focus (combo_entry);
+        }
+      else
+        {
+	   gtk_widget_grab_focus (combo_box->priv->button);
+        }
+    }
+}