diff --git a/gtk/gtksearchentry.c b/gtk/gtksearchentry.c
index c29faab..d0d8e8e 100644
--- a/gtk/gtksearchentry.c
+++ b/gtk/gtksearchentry.c
@@ -28,6 +28,8 @@
 #include "config.h"
 
 #include "gtksearchentry.h"
+#include "gtkmarshalers.h"
+#include "gtkintl.h"
 
 /**
  * SECTION:gtksearchentry
@@ -63,6 +65,14 @@ typedef struct {
  * that we cannot now have one without breaking ABI */
 #define GET_PRIV(e) G_TYPE_INSTANCE_GET_PRIVATE (e, GTK_TYPE_SEARCH_ENTRY, GtkSearchEntryPrivate)
 
+enum
+{
+  SLOW_CHANGED,
+  LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
 static void
 gtk_search_entry_finalize (GObject *object)
 {
@@ -82,6 +92,17 @@ gtk_search_entry_class_init (GtkSearchEntryClass *klass)
   object_class->finalize = gtk_search_entry_finalize;
 
   g_type_class_add_private (klass, sizeof (GtkSearchEntryPrivate));
+
+  klass->slow_changed = NULL;
+
+  signals[SLOW_CHANGED] =
+    g_signal_new (I_("slow-changed"),
+                  G_OBJECT_CLASS_TYPE (object_class),
+                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+                  G_STRUCT_OFFSET (GtkSearchEntryClass, slow_changed),
+                  NULL, NULL,
+                  _gtk_marshal_VOID__VOID,
+                  G_TYPE_NONE, 0);
 }
 
 static void
@@ -92,13 +113,13 @@ search_entry_clear_cb (GtkEntry *entry,
 }
 
 static gboolean
-gtk_search_entry_changed_timeout_cb (gpointer user_data)
+gtk_search_entry_slow_changed_timeout_cb (gpointer user_data)
 {
   GtkSearchEntry *entry = user_data;
   GtkSearchEntryPrivate *priv = GET_PRIV (entry);
 
   priv->in_timeout = TRUE;
-  g_signal_emit_by_name (entry, "changed");
+  g_signal_emit (entry, signals[SLOW_CHANGED], 0);
   priv->delayed_changed_id = 0;
   priv->in_timeout = FALSE;
 
@@ -112,19 +133,36 @@ reset_timeout (GtkSearchEntry *entry)
 
   if (priv->delayed_changed_id > 0)
     g_source_remove (priv->delayed_changed_id);
-  priv->delayed_changed_id = g_timeout_add (DELAYED_TIMEOUT_ID,
-                                            gtk_search_entry_changed_timeout_cb,
-                                            entry);
+
+  priv->delayed_changed_id =
+    g_timeout_add (DELAYED_TIMEOUT_ID,
+                   gtk_search_entry_slow_changed_timeout_cb,
+                   entry);
+}
+
+static void
+search_entry_slow_changed_cb (GtkSearchEntry *entry,
+                              gpointer        user_data)
+{
+  GtkSearchEntryPrivate *priv = GET_PRIV (entry);
+
+  /* Don't stop the emission if it's the timeout
+   * emitting the signal, otherwise we'll get in a loop */
+  if (priv->in_timeout)
+    return;
+
+  /* Queue up the timeout */
+  reset_timeout (entry);
+  g_signal_stop_emission (entry, signals[SLOW_CHANGED], 0);
 }
 
 static void
 search_entry_changed_cb (GtkSearchEntry *entry,
                          gpointer        user_data)
 {
-  GtkSearchEntryPrivate *priv = GET_PRIV (entry);
   const char *str, *icon_name;
   gboolean active;
-  gboolean cleared = FALSE;
+  gboolean not_cleared = TRUE;
 
   /* Update the icons first */
   str = gtk_entry_get_text (GTK_ENTRY (entry));
@@ -133,7 +171,7 @@ search_entry_changed_cb (GtkSearchEntry *entry,
     {
       icon_name = NULL;
       active = FALSE;
-      cleared = TRUE;
+      not_cleared = FALSE;
     }
   else
     {
@@ -150,24 +188,17 @@ search_entry_changed_cb (GtkSearchEntry *entry,
                 "secondary-icon-sensitive", active,
                 NULL);
 
-  /* Don't stop the emission if it's the timeout
-   * emitting the signal, otherwise we'll get in a loop */
-  if (priv->in_timeout)
-    return;
-
   /* Don't emit the signal in a timeout if we've cleared
    * the entry, we don't want a delay */
-  if (cleared)
-    return;
-
-  /* Queue up the timeout */
-  reset_timeout (entry);
-  g_signal_stop_emission_by_name (entry, "changed");
+  if (not_cleared)
+    g_signal_emit (entry, signals[SLOW_CHANGED], 0);
 }
 
 static void
 gtk_search_entry_init (GtkSearchEntry *entry)
 {
+  g_signal_connect (entry, "slow-changed",
+                    G_CALLBACK (search_entry_slow_changed_cb), NULL);
   g_signal_connect (entry, "changed",
                     G_CALLBACK (search_entry_changed_cb), NULL);
   g_signal_connect (entry, "icon-release",
diff --git a/gtk/gtksearchentry.h b/gtk/gtksearchentry.h
index 7f274ba..e409e7d 100644
--- a/gtk/gtksearchentry.h
+++ b/gtk/gtksearchentry.h
@@ -55,11 +55,13 @@ struct _GtkSearchEntryClass
 {
   GtkEntryClass parent_class;
 
+  /* signal */
+  void (* slow_changed)  (GtkSearchEntry    *search_entry);
+
   /* Padding for future expansion */
   void (*_gtk_reserved1) (void);
   void (*_gtk_reserved2) (void);
   void (*_gtk_reserved3) (void);
-  void (*_gtk_reserved4) (void);
 };
 
 GDK_AVAILABLE_IN_3_6
