Index: gtk/gtk.symbols
===================================================================
--- gtk/gtk.symbols	(revision 21330)
+++ gtk/gtk.symbols	(working copy)
@@ -1270,6 +1270,8 @@ gtk_entry_get_layout
 gtk_entry_get_layout_offsets
 gtk_entry_get_max_length
 gtk_entry_get_overwrite_mode
+gtk_entry_get_progress_fraction
+gtk_entry_get_progress_pulse_step
 gtk_entry_get_text
 gtk_entry_get_text_length
 gtk_entry_get_type G_GNUC_CONST
@@ -1281,6 +1283,7 @@ gtk_entry_new
 gtk_entry_new_with_max_length
 gtk_entry_append_text
 gtk_entry_prepend_text
+gtk_entry_progress_pulse
 gtk_entry_select_region
 gtk_entry_set_position
 gtk_entry_set_editable
@@ -1293,6 +1296,8 @@ gtk_entry_set_inner_border
 gtk_entry_set_invisible_char
 gtk_entry_set_max_length
 gtk_entry_set_overwrite_mode
+gtk_entry_set_progress_fraction
+gtk_entry_set_progress_pulse_step
 gtk_entry_set_text
 gtk_entry_set_visibility
 gtk_entry_set_width_chars
Index: gtk/gtkentry.c
===================================================================
--- gtk/gtkentry.c	(revision 21330)
+++ gtk/gtkentry.c	(working copy)
@@ -22,10 +22,12 @@
  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
  * file for a list of people on the GTK+ Team.  See the ChangeLog
  * files for a list of changes.  These files are distributed with
- * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
  */
 
 #include "config.h"
+
+#include <math.h>
 #include <string.h>
 
 #include <pango/pango.h>
@@ -85,12 +87,18 @@ struct _GtkEntryPrivate 
   gfloat xalign;
   gint insert_pos;
   guint blink_time;  /* time in msec the cursor has blinked since last user event */
-  guint interior_focus : 1;
-  guint real_changed   : 1;
-  guint change_count   : 8;
+  guint interior_focus          : 1;
+  guint real_changed            : 1;
+  guint change_count            : 8;
+  guint progress_pulse_mode     : 1;
+  guint progress_pulse_way_back : 1;
 
   gint focus_width;
   GtkShadowType shadow_type;
+
+  gdouble progress_fraction;
+  gdouble progress_pulse_fraction;
+  gdouble progress_pulse_current;
 };
 
 typedef struct _GtkEntryPasswordHint GtkEntryPasswordHint;
@@ -170,6 +178,8 @@ static void   gtk_entry_size_allocate   
 					      GtkAllocation    *allocation);
 static void   gtk_entry_draw_frame           (GtkWidget        *widget,
                                               GdkRectangle     *area);
+static void   gtk_entry_draw_progress        (GtkWidget        *widget,
+                                              GdkEventExpose   *event);
 static gint   gtk_entry_expose               (GtkWidget        *widget,
 					      GdkEventExpose   *event);
 static gint   gtk_entry_button_press         (GtkWidget        *widget,
@@ -1162,6 +1172,8 @@ gtk_entry_init (GtkEntry *entry)
   entry->truncate_multiline = FALSE;
   priv->shadow_type = GTK_SHADOW_IN;
   priv->xalign = 0.0;
+  priv->progress_fraction = 0.0;
+  priv->progress_pulse_fraction = 0.1;
 
   gtk_drag_dest_set (GTK_WIDGET (entry),
                      GTK_DEST_DEFAULT_HIGHLIGHT,
@@ -1648,6 +1660,52 @@ gtk_entry_draw_frame (GtkWidget    *widg
     }
 }
 
+static void
+gtk_entry_draw_progress (GtkWidget      *widget,
+                         GdkEventExpose *event)
+{
+  GtkEntryPrivate *private = GTK_ENTRY_GET_PRIVATE (widget);
+  GtkEntry *entry = GTK_ENTRY (widget);
+
+  if (private->progress_pulse_mode)
+    {
+      gdouble value = private->progress_pulse_current;
+      gint    area_width, area_height;
+
+      gdk_drawable_get_size (entry->text_area, &area_width, &area_height);
+
+      gtk_paint_box (widget->style, entry->text_area,
+                     GTK_STATE_SELECTED, GTK_SHADOW_OUT,
+                     &event->area, widget, "bar",
+                     value * area_width, 0,
+                     private->progress_pulse_fraction * area_width, area_height);
+    }
+  else if (private->progress_fraction > 0)
+    {
+      gdouble value = private->progress_fraction;
+      gint    area_width, area_height;
+
+      gdk_drawable_get_size (entry->text_area, &area_width, &area_height);
+
+      if (gtk_widget_get_direction (GTK_WIDGET (entry)) == GTK_TEXT_DIR_RTL)
+        {
+          gtk_paint_box (widget->style, entry->text_area,
+                         GTK_STATE_SELECTED, GTK_SHADOW_OUT,
+                         &event->area, widget, "bar",
+                         area_width - value * area_width, 0,
+                         value * area_width, area_height);
+        }
+      else
+        {
+          gtk_paint_box (widget->style, entry->text_area,
+                         GTK_STATE_SELECTED, GTK_SHADOW_OUT,
+                         &event->area, widget, "bar",
+                         0, 0,
+                         value * area_width, area_height);
+        }
+    }
+}
+
 static gint
 gtk_entry_expose (GtkWidget      *widget,
 		  GdkEventExpose *event)
@@ -1666,6 +1724,8 @@ gtk_entry_expose (GtkWidget      *widget
 			  &event->area, widget, "entry_bg",
 			  0, 0, area_width, area_height);
 
+      gtk_entry_draw_progress (widget, event);
+
       if (entry->dnd_position != -1)
 	gtk_entry_draw_cursor (GTK_ENTRY (widget), CURSOR_DND);
       
@@ -6451,5 +6511,173 @@ gtk_entry_get_cursor_hadjustment (GtkEnt
   return g_object_get_qdata (G_OBJECT (entry), quark_cursor_hadjustment);
 }
 
+/**
+ * gtk_entry_set_progress_fraction:
+ * @entry: a #GtkEntry
+ * @fraction: fraction of the task that's been completed
+ *
+ * Causes the entry's progress indicator to "fill in" the given
+ * fraction of the bar. The fraction should be between 0.0 and 1.0,
+ * inclusive.
+ *
+ * Since: 2.16
+ */
+void
+gtk_entry_set_progress_fraction (GtkEntry *entry,
+                                 gdouble   fraction)
+{
+  GtkEntryPrivate *private;
+  gdouble          old_fraction;
+
+  g_return_if_fail (GTK_IS_ENTRY (entry));
+
+  private = GTK_ENTRY_GET_PRIVATE (entry);
+
+  if (private->progress_pulse_mode)
+    old_fraction = -1;
+  else
+    old_fraction = private->progress_fraction;
+
+  fraction = CLAMP (fraction, 0.0, 1.0);
+
+  private->progress_fraction = fraction;
+  private->progress_pulse_mode = FALSE;
+  private->progress_pulse_current = 0.0;
+
+  if (fabs (fraction - old_fraction) > 0.0001)
+    gtk_entry_queue_draw (entry);
+}
+
+/**
+ * gtk_entry_get_progress_fraction:
+ * @entry: a #GtkEntry
+ *
+ * Returns the current fraction of the task that's been completed.
+ * See gtk_entry_set_progress_fraction().
+ *
+ * Return value: a fraction from 0.0 to 1.0
+ *
+ * Since: 2.16
+ */
+gdouble
+gtk_entry_get_progress_fraction (GtkEntry *entry)
+{
+  GtkEntryPrivate *private;
+
+  g_return_val_if_fail (GTK_IS_ENTRY (entry), 0.0);
+
+  private = GTK_ENTRY_GET_PRIVATE (entry);
+
+  return private->progress_fraction;
+}
+
+/**
+ * gtk_entry_set_progress_pulse_step:
+ * @entry: a #GtkEntry
+ * @fraction: fraction between 0.0 and 1.0
+ *
+ * Sets the fraction of total entry width to move the progress
+ * bouncing block for each call to gtk_entry_progress_pulse().
+ *
+ * Since: 2.16
+ */
+void
+gtk_entry_set_progress_pulse_step (GtkEntry *entry,
+                                   gdouble   fraction)
+{
+  GtkEntryPrivate *private;
+
+  g_return_if_fail (GTK_IS_ENTRY (entry));
+
+  private = GTK_ENTRY_GET_PRIVATE (entry);
+
+  fraction = CLAMP (fraction, 0.0, 1.0);
+
+  if (fraction != private->progress_pulse_fraction)
+    {
+      private->progress_pulse_fraction = fraction;
+
+      gtk_entry_queue_draw (entry);
+    }
+}
+
+/**
+ * gtk_entry_get_progress_pulse_step:
+ * @entry: a #GtkEntry
+ *
+ * Retrieves the pulse step set with gtk_entry_set_progress_pulse_step().
+ *
+ * Return value: a fraction from 0.0 to 1.0
+ *
+ * Since: 2.16
+ */
+gdouble
+gtk_entry_get_progress_pulse_step (GtkEntry *entry)
+{
+  GtkEntryPrivate *private;
+
+  g_return_val_if_fail (GTK_IS_ENTRY (entry), 0.0);
+
+  private = GTK_ENTRY_GET_PRIVATE (entry);
+
+  return private->progress_pulse_fraction;
+}
+
+/**
+ * gtk_entry_progress_pulse:
+ * @entry: a #GtkEntry
+ *
+ * Indicates that some progress is made, but you don't know how much.
+ * Causes the entry's progress indicator to enter "activity mode,"
+ * where a block bounces back and forth. Each call to
+ * gtk_entry_progress_pulse() causes the block to move by a little bit
+ * (the amount of movement per pulse is determined by
+ * gtk_entry_set_progress_pulse_step()).
+ *
+ * Since: 2.16
+ */
+void
+gtk_entry_progress_pulse (GtkEntry *entry)
+{
+  GtkEntryPrivate *private;
+
+  g_return_if_fail (GTK_IS_ENTRY (entry));
+
+  private = GTK_ENTRY_GET_PRIVATE (entry);
+
+  if (private->progress_pulse_mode)
+    {
+      if (private->progress_pulse_way_back)
+        {
+          private->progress_pulse_current -= private->progress_pulse_fraction;
+
+          if (private->progress_pulse_current < 0.0)
+            {
+              private->progress_pulse_current = 0.0;
+              private->progress_pulse_way_back = FALSE;
+            }
+        }
+      else
+        {
+          private->progress_pulse_current += private->progress_pulse_fraction;
+
+          if (private->progress_pulse_current > 1.0 - private->progress_pulse_fraction)
+            {
+              private->progress_pulse_current = 1.0 - private->progress_pulse_fraction;
+              private->progress_pulse_way_back = TRUE;
+            }
+        }
+    }
+  else
+    {
+      private->progress_fraction = 0.0;
+      private->progress_pulse_mode = TRUE;
+      private->progress_pulse_way_back = FALSE;
+      private->progress_pulse_current = 0.0;
+    }
+
+  gtk_entry_queue_draw (entry);
+}
+
 #define __GTK_ENTRY_C__
 #include "gtkaliasdef.c"
Index: gtk/gtkentry.h
===================================================================
--- gtk/gtkentry.h	(revision 21330)
+++ gtk/gtkentry.h	(working copy)
@@ -212,6 +212,18 @@ void           gtk_entry_set_cursor_hadj
                                                  GtkAdjustment *adjustment);
 GtkAdjustment* gtk_entry_get_cursor_hadjustment (GtkEntry      *entry);
 
+/* Progress API
+ */
+void           gtk_entry_set_progress_fraction   (GtkEntry     *entry,
+                                                  gdouble       fraction);
+gdouble        gtk_entry_get_progress_fraction   (GtkEntry     *entry);
+
+void           gtk_entry_set_progress_pulse_step (GtkEntry     *entry,
+                                                  gdouble       fraction);
+gdouble        gtk_entry_get_progress_pulse_step (GtkEntry     *entry);
+
+void           gtk_entry_progress_pulse          (GtkEntry     *entry);
+
 /* Deprecated compatibility functions
  */
 
Index: tests/testgtk.c
===================================================================
--- tests/testgtk.c	(revision 21330)
+++ tests/testgtk.c	(working copy)
@@ -5193,6 +5193,65 @@ entry_toggle_sensitive (GtkWidget *check
    gtk_widget_set_sensitive (entry, GTK_TOGGLE_BUTTON(checkbutton)->active);
 }
 
+static gboolean
+entry_progress_timeout (gpointer data)
+{
+  if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (data), "progress-pulse")))
+    {
+      gtk_entry_progress_pulse (GTK_ENTRY (data));
+    }
+  else
+    {
+      gdouble fraction;
+
+      fraction = gtk_entry_get_progress_fraction (GTK_ENTRY (data));
+
+      fraction += 0.05;
+      if (fraction > 1.0001)
+        fraction = 0.0;
+
+      gtk_entry_set_progress_fraction (GTK_ENTRY (data), fraction);
+    }
+
+  return TRUE;
+}
+
+static void
+entry_remove_timeout (gpointer data)
+{
+  g_source_remove (GPOINTER_TO_UINT (data));
+}
+
+static void
+entry_toggle_progress (GtkWidget *checkbutton,
+                       GtkWidget *entry)
+{
+  if (GTK_TOGGLE_BUTTON (checkbutton)->active)
+    {
+      guint timeout = gdk_threads_add_timeout (100,
+                                               entry_progress_timeout,
+                                               entry);
+      g_object_set_data_full (G_OBJECT (entry), "timeout-id",
+                              GUINT_TO_POINTER (timeout),
+                              entry_remove_timeout);
+    }
+  else
+    {
+      g_object_set_data (G_OBJECT (entry), "timeout-id",
+                         GUINT_TO_POINTER (0));
+
+      gtk_entry_set_progress_fraction (GTK_ENTRY (entry), 0.0);
+    }
+}
+
+static void
+entry_toggle_pulse (GtkWidget *checkbutton,
+                    GtkWidget *entry)
+{
+  g_object_set_data (G_OBJECT (entry), "progress-pulse",
+                     GINT_TO_POINTER (GTK_TOGGLE_BUTTON (checkbutton)->active));
+}
+
 static void
 entry_props_clicked (GtkWidget *button,
 		     GObject   *entry)
@@ -5211,6 +5270,7 @@ create_entry (GtkWidget *widget)
   GtkWidget *hbox;
   GtkWidget *has_frame_check;
   GtkWidget *sensitive_check;
+  GtkWidget *progress_check;
   GtkWidget *entry, *cb;
   GtkWidget *button;
   GtkWidget *separator;
@@ -5281,7 +5341,17 @@ create_entry (GtkWidget *widget)
       g_signal_connect (has_frame_check, "toggled",
 			G_CALLBACK (entry_toggle_frame), entry);
       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (has_frame_check), TRUE);
-      
+
+      progress_check = gtk_check_button_new_with_label("Show Progress");
+      gtk_box_pack_start (GTK_BOX (box2), progress_check, FALSE, TRUE, 0);
+      g_signal_connect (progress_check, "toggled",
+			G_CALLBACK (entry_toggle_progress), entry);
+
+      progress_check = gtk_check_button_new_with_label("Pulse Progress");
+      gtk_box_pack_start (GTK_BOX (box2), progress_check, FALSE, TRUE, 0);
+      g_signal_connect (progress_check, "toggled",
+			G_CALLBACK (entry_toggle_pulse), entry);
+
       separator = gtk_hseparator_new ();
       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
 
