Index: gtk/gtkentry.c
===================================================================
--- gtk/gtkentry.c	(revision 17550)
+++ gtk/gtkentry.c	(working copy)
@@ -5718,22 +5718,22 @@
            event->keyval == GDK_KP_Enter ||
 	   event->keyval == GDK_Return)
     {
+      GtkTreeIter iter;
+      GtkTreeModel *model;
+      gint index;
+
       _gtk_entry_reset_im_context (GTK_ENTRY (widget));
       _gtk_entry_completion_popdown (completion);
 
-      if (completion->priv->current_selected < matches)
+      if (!_gtk_entry_completion_get_selected (completion, &model, &iter, &index))
+        return FALSE;
+
+      if (index < 0)
         {
-          GtkTreeIter iter;
-          GtkTreeModel *model = NULL;
-          GtkTreeSelection *sel;
           gboolean entry_set;
 
-          sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (completion->priv->tree_view));
-          if (!gtk_tree_selection_get_selected (sel, &model, &iter))
-            return FALSE;
-
 	  g_signal_handler_block (widget, completion->priv->changed_id);
-          g_signal_emit_by_name (completion, "match_selected",
+          g_signal_emit_by_name (completion, "match_selected", 
                                  model, &iter, &entry_set);
 	  g_signal_handler_unblock (widget, completion->priv->changed_id);
 
@@ -5752,23 +5752,19 @@
 
              g_free (str);
             }
-
-          return TRUE;
         }
-      else if (completion->priv->current_selected - matches >= 0)
+      else 
         {
           GtkTreePath *path;
 
-          _gtk_entry_reset_im_context (GTK_ENTRY (widget));
+          path = gtk_tree_path_new_from_indices (index, -1);
 
-          path = gtk_tree_path_new_from_indices (completion->priv->current_selected - matches, -1);
-
           g_signal_emit_by_name (completion, "action_activated",
                                  gtk_tree_path_get_indices (path)[0]);
           gtk_tree_path_free (path);
-
-          return TRUE;
         }
+
+      return TRUE;
     }
 
   return FALSE;
Index: gtk/gtkentrycompletion.c
===================================================================
--- gtk/gtkentrycompletion.c	(revision 17550)
+++ gtk/gtkentrycompletion.c	(working copy)
@@ -47,6 +47,7 @@
   INSERT_PREFIX,
   MATCH_SELECTED,
   ACTION_ACTIVATED,
+  KEY_EVENT,
   LAST_SIGNAL
 };
 
@@ -230,6 +231,19 @@
                   G_TYPE_NONE, 1,
                   G_TYPE_INT);
 
+  entry_completion_signals[KEY_EVENT] =
+    g_signal_new (I_("key_event"),
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  _gtk_boolean_handled_accumulator, NULL,
+                  _gtk_marshal_BOOLEAN__OBJECT_BOXED_INT_BOXED,
+                  G_TYPE_BOOLEAN, 4,
+                  GTK_TYPE_TREE_MODEL,
+                  GTK_TYPE_TREE_ITER,
+                  G_TYPE_INT,
+                  GDK_TYPE_EVENT);
+
   g_object_class_install_property (object_class,
                                    PROP_MODEL,
                                    g_param_spec_object ("model",
@@ -756,10 +770,24 @@
                                       gpointer     user_data)
 {
   GtkEntryCompletion *completion = GTK_ENTRY_COMPLETION (user_data);
+  GtkTreeModel *model;
+  GtkTreeIter iter;
+  gint index;
 
   if (!GTK_WIDGET_MAPPED (completion->priv->popup_window))
     return FALSE;
 
+  if (_gtk_entry_completion_get_selected (completion, &model, &iter, &index))
+    {
+      gboolean handled = FALSE;
+
+      g_signal_emit (completion, entry_completion_signals[KEY_EVENT], 
+                     0, model, &iter, index, event, &handled);
+
+      if (handled)
+        return TRUE;
+    }
+
   /* propagate event to the entry */
   gtk_widget_event (completion->priv->entry, (GdkEvent *)event);
 
@@ -797,18 +825,20 @@
                                      event->x, event->y,
                                      &path, NULL, NULL, NULL))
     {
-      GtkTreeIter iter;
+      GtkTreeIter iter, child_iter;
+      GtkTreeModel *child_model;
       gboolean entry_set;
 
       gtk_tree_model_get_iter (GTK_TREE_MODEL (completion->priv->filter_model),
                                &iter, path);
       gtk_tree_path_free (path);
 
+      gtk_tree_model_filter_convert_iter_to_child_iter (completion->priv->filter_model, &child_iter, &iter);
+      child_model = gtk_tree_model_filter_get_model (completion->priv->filter_model);
       g_signal_handler_block (completion->priv->entry,
 			      completion->priv->changed_id);
       g_signal_emit (completion, entry_completion_signals[MATCH_SELECTED],
-                     0, GTK_TREE_MODEL (completion->priv->filter_model),
-                     &iter, &entry_set);
+                     0, child_model, &child_iter, &entry_set);
       g_signal_handler_unblock (completion->priv->entry,
 				completion->priv->changed_id);
 
@@ -1782,6 +1812,38 @@
   return completion->priv->popup_single_match;
 }
 
+gboolean 
+_gtk_entry_completion_get_selected (GtkEntryCompletion  *completion,
+                                    GtkTreeModel       **model,
+                                    GtkTreeIter         *iter,
+                                    gint                *index_)
+{
+  gint matches, actions;
 
+  if (completion->priv->current_selected < 0)
+    return FALSE;
+
+  matches = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (completion->priv->filter_model), NULL);
+
+  *index_ = completion->priv->current_selected - matches;
+
+  if (completion->priv->current_selected < matches)
+    {
+      GtkTreeIter filter_iter;
+      GtkTreeModel *filter_model;
+      GtkTreeSelection *sel;
+
+      sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (completion->priv->tree_view));
+      if (!gtk_tree_selection_get_selected (sel, &filter_model, &filter_iter))
+        return FALSE;
+
+      *model = gtk_tree_model_filter_get_model (completion->priv->filter_model);
+      gtk_tree_model_filter_convert_iter_to_child_iter (completion->priv->filter_model, iter, &filter_iter);
+    }
+
+  return TRUE;
+}
+
+
 #define __GTK_ENTRY_COMPLETION_C__
 #include "gtkaliasdef.c"
Index: gtk/gtkentryprivate.h
===================================================================
--- gtk/gtkentryprivate.h	(revision 17550)
+++ gtk/gtkentryprivate.h	(working copy)
@@ -70,6 +70,10 @@
 gboolean _gtk_entry_completion_resize_popup (GtkEntryCompletion *completion);
 void     _gtk_entry_completion_popup        (GtkEntryCompletion *completion);
 void     _gtk_entry_completion_popdown      (GtkEntryCompletion *completion);
+gboolean _gtk_entry_completion_get_selected (GtkEntryCompletion  *completion,
+                                             GtkTreeModel       **model, 
+                                             GtkTreeIter         *iter,
+                                             gint                *index_);
 
 void      _gtk_entry_get_borders            (GtkEntry  *entry,
 					     gint      *xborder,
Index: gtk/gtkmarshalers.list
===================================================================
--- gtk/gtkmarshalers.list	(revision 17550)
+++ gtk/gtkmarshalers.list	(working copy)
@@ -33,6 +33,7 @@
 BOOLEAN:OBJECT,STRING,STRING,BOXED
 BOOLEAN:OBJECT,BOXED
 BOOLEAN:OBJECT,BOXED,BOXED
+BOOLEAN:OBJECT,BOXED,INT,BOXED
 BOOLEAN:OBJECT,OBJECT,OBJECT
 BOOLEAN:OBJECT,STRING,STRING
 BOOLEAN:OBJECT,ENUM
