Index: gtk/gtkcombobox.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkcombobox.c,v
retrieving revision 1.182
diff -u -p -r1.182 gtkcombobox.c
--- gtk/gtkcombobox.c	14 Aug 2006 20:12:10 -0000	1.182
+++ gtk/gtkcombobox.c	29 Sep 2006 12:56:42 -0000
@@ -186,6 +186,7 @@ struct _GtkComboBoxPrivate
 
 enum {
   CHANGED,
+  MOVE_CURRENT,
   LAST_SIGNAL
 };
 
@@ -291,6 +292,8 @@ static gboolean gtk_combo_box_key_press 
 
 static void     gtk_combo_box_check_appearance     (GtkComboBox      *combo_box);
 static gchar *  gtk_combo_box_real_get_active_text (GtkComboBox      *combo_box);
+static void     gtk_combo_box_real_move_current    (GtkComboBox      *combo_box,
+                                                    GtkScrollType     scroll);
 
 /* listening to the model */
 static void     gtk_combo_box_model_row_inserted   (GtkTreeModel     *model,
@@ -456,8 +459,10 @@ gtk_combo_box_class_init (GtkComboBoxCla
   GtkObjectClass *gtk_object_class;
   GtkContainerClass *container_class;
   GtkWidgetClass *widget_class;
+  GtkBindingSet *binding_set;
 
   klass->get_active_text = gtk_combo_box_real_get_active_text;
+  klass->move_current = gtk_combo_box_real_move_current;
 
   container_class = (GtkContainerClass *)klass;
   container_class->forall = gtk_combo_box_forall;
@@ -505,6 +510,57 @@ gtk_combo_box_class_init (GtkComboBoxCla
                   g_cclosure_marshal_VOID__VOID,
                   G_TYPE_NONE, 0);
 
+  combo_box_signals[MOVE_CURRENT] =
+    g_signal_new (I_("move-current"),
+                  G_OBJECT_CLASS_TYPE (klass),
+                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+                  G_STRUCT_OFFSET (GtkComboBoxClass, move_current),
+                  NULL, NULL,
+                  g_cclosure_marshal_VOID__ENUM,
+                  G_TYPE_NONE, 1,
+                  GTK_TYPE_SCROLL_TYPE);
+
+  /* key bindings */
+  binding_set = gtk_binding_set_by_class (widget_class);
+
+  gtk_binding_entry_add_signal (binding_set, GDK_Up, 0,
+				"move-current", 1,
+				GTK_TYPE_SCROLL_TYPE, GTK_SCROLL_STEP_UP);
+  gtk_binding_entry_add_signal (binding_set, GDK_KP_Up, 0,
+				"move-current", 1,
+				GTK_TYPE_SCROLL_TYPE, GTK_SCROLL_STEP_UP);
+  gtk_binding_entry_add_signal (binding_set, GDK_Page_Up, 0,
+				"move-current", 1,
+				GTK_TYPE_SCROLL_TYPE, GTK_SCROLL_PAGE_UP);
+  gtk_binding_entry_add_signal (binding_set, GDK_KP_Page_Up, 0,
+				"move-current", 1,
+				GTK_TYPE_SCROLL_TYPE, GTK_SCROLL_PAGE_UP);
+  gtk_binding_entry_add_signal (binding_set, GDK_Home, 0,
+				"move-current", 1,
+				GTK_TYPE_SCROLL_TYPE, GTK_SCROLL_START);
+  gtk_binding_entry_add_signal (binding_set, GDK_KP_Home, 0,
+				"move-current", 1,
+				GTK_TYPE_SCROLL_TYPE, GTK_SCROLL_START);
+
+  gtk_binding_entry_add_signal (binding_set, GDK_Down, 0,
+				"move-current", 1,
+				GTK_TYPE_SCROLL_TYPE, GTK_SCROLL_STEP_DOWN);
+  gtk_binding_entry_add_signal (binding_set, GDK_KP_Down, 0,
+				"move-current", 1,
+				GTK_TYPE_SCROLL_TYPE, GTK_SCROLL_STEP_DOWN);
+  gtk_binding_entry_add_signal (binding_set, GDK_Page_Down, 0,
+				"move-current", 1,
+				GTK_TYPE_SCROLL_TYPE, GTK_SCROLL_PAGE_DOWN);
+  gtk_binding_entry_add_signal (binding_set, GDK_KP_Page_Down, 0,
+				"move-current", 1,
+				GTK_TYPE_SCROLL_TYPE, GTK_SCROLL_PAGE_DOWN);
+  gtk_binding_entry_add_signal (binding_set, GDK_End, 0,
+				"move-current", 1,
+				GTK_TYPE_SCROLL_TYPE, GTK_SCROLL_END);
+  gtk_binding_entry_add_signal (binding_set, GDK_KP_End, 0,
+				"move-current", 1,
+				GTK_TYPE_SCROLL_TYPE, GTK_SCROLL_END);
+
   /* properties */
   /**
    * GtkComboBox:model:
@@ -3566,9 +3622,6 @@ gtk_combo_box_key_press (GtkWidget   *wi
 {
   GtkComboBox *combo_box = GTK_COMBO_BOX (data);
   guint state = event->state & gtk_accelerator_get_default_mod_mask ();
-  gboolean found;
-  GtkTreeIter iter;
-  GtkTreeIter new_iter;
 
   if (combo_box->priv->model == NULL)
     return FALSE;
@@ -3581,50 +3634,7 @@ gtk_combo_box_key_press (GtkWidget   *wi
       return TRUE;
     }
 
-  if (state != 0)
-    return FALSE;
-
-  switch (event->keyval) 
-    {
-    case GDK_Down:
-    case GDK_KP_Down:
-      if (gtk_combo_box_get_active_iter (combo_box, &iter))
-	{
-	  found = tree_next (combo_box, combo_box->priv->model, 
-			     &iter, &new_iter, FALSE);
-	  break;
-	}
-      /* else fall through */
-    case GDK_Page_Up:
-    case GDK_KP_Page_Up:
-    case GDK_Home: 
-    case GDK_KP_Home:
-      found = tree_first (combo_box, combo_box->priv->model, &new_iter, FALSE);
-      break;
-
-    case GDK_Up:
-    case GDK_KP_Up:
-      if (gtk_combo_box_get_active_iter (combo_box, &iter))
-	{
-	  found = tree_prev (combo_box, combo_box->priv->model, 
-			     &iter, &new_iter, FALSE);
-	  break;
-	}
-      /* else fall through */      
-    case GDK_Page_Down:
-    case GDK_KP_Page_Down:
-    case GDK_End: 
-    case GDK_KP_End:
-      found = tree_last (combo_box, combo_box->priv->model, &new_iter, FALSE);
-      break;
-    default:
-      return FALSE;
-    }
-      
-  if (found)
-    gtk_combo_box_set_active_iter (combo_box, &new_iter);
-  
-  return TRUE;
+  return FALSE;
 }
 
 static gboolean
@@ -4933,6 +4943,84 @@ gtk_combo_box_real_get_active_text (GtkC
 			0, &text, -1);
 
   return text;
+}
+
+static void
+gtk_combo_box_real_move_current (GtkComboBox   *combo_box,
+                                 GtkScrollType  scroll)
+{
+  GtkTreeIter iter;
+  GtkTreeIter new_iter;
+  gboolean    active_iter;
+  gboolean    found;
+
+  active_iter = gtk_combo_box_get_active_iter (combo_box, &iter);
+
+  switch (scroll)
+    {
+    case GTK_SCROLL_STEP_BACKWARD:
+    case GTK_SCROLL_STEP_UP:
+    case GTK_SCROLL_STEP_LEFT:
+      if (active_iter)
+        {
+	  found = tree_prev (combo_box, combo_box->priv->model,
+			     &iter, &new_iter, FALSE);
+	  break;
+        }
+      /* else fall through */
+
+    case GTK_SCROLL_PAGE_BACKWARD:
+    case GTK_SCROLL_PAGE_UP:
+    case GTK_SCROLL_PAGE_LEFT:
+    case GTK_SCROLL_START:
+      found = tree_first (combo_box, combo_box->priv->model, &new_iter, FALSE);
+      break;
+
+    case GTK_SCROLL_STEP_FORWARD:
+    case GTK_SCROLL_STEP_DOWN:
+    case GTK_SCROLL_STEP_RIGHT:
+      if (active_iter)
+        {
+	  found = tree_next (combo_box, combo_box->priv->model,
+			     &iter, &new_iter, FALSE);
+          break;
+        }
+      /* else fall through */
+
+    case GTK_SCROLL_PAGE_FORWARD:
+    case GTK_SCROLL_PAGE_DOWN:
+    case GTK_SCROLL_PAGE_RIGHT:
+    case GTK_SCROLL_END:
+      found = tree_last (combo_box, combo_box->priv->model, &new_iter, FALSE);
+      break;
+
+    default:
+      return;
+    }
+
+  if (found)
+    {
+      if (active_iter)
+        {
+          GtkTreePath *old_path;
+          GtkTreePath *new_path;
+
+          old_path = gtk_tree_model_get_path (combo_box->priv->model, &iter);
+          new_path = gtk_tree_model_get_path (combo_box->priv->model, &new_iter);
+
+          if (gtk_tree_path_compare (old_path, new_path) == 0)
+            found = FALSE;
+
+          gtk_tree_path_free (old_path);
+          gtk_tree_path_free (new_path);
+        }
+
+      if (found)
+        {
+          gtk_combo_box_set_active_iter (combo_box, &new_iter);
+          return;
+        }
+    }
 }
 
 static gboolean
Index: gtk/gtkcombobox.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkcombobox.h,v
retrieving revision 1.26
diff -u -p -r1.26 gtkcombobox.h
--- gtk/gtkcombobox.h	21 Nov 2005 16:01:49 -0000	1.26
+++ gtk/gtkcombobox.h	29 Sep 2006 12:56:45 -0000
@@ -55,8 +55,11 @@ struct _GtkComboBoxClass
   /* vfuncs */
   gchar *  (* get_active_text)  (GtkComboBox *combo_box);
 
+  /* signals */
+  void     (* move_current)     (GtkComboBox   *combo_box,
+                                 GtkScrollType  scroll);
+
   /* Padding for future expansion */
-  void (*_gtk_reserved0) (void);
   void (*_gtk_reserved1) (void);
   void (*_gtk_reserved2) (void);
 };
