diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c
index c5e3a6e..450605b 100644
--- a/gtk/gtkentry.c
+++ b/gtk/gtkentry.c
@@ -171,6 +171,7 @@ enum {
   TOGGLE_OVERWRITE,
   ICON_PRESS,
   ICON_RELEASE,
+  PREEDIT_CHANGED,
   LAST_SIGNAL
 };
 
@@ -1550,6 +1551,27 @@ gtk_entry_class_init (GtkEntryClass *class)
                   GTK_TYPE_ENTRY_ICON_POSITION,
                   GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
 
+  /**
+   * GtkEntry::preedit-changed:
+   * @entry: the object which received the signal
+   * @preedit: the current preedit string
+   *
+   * If an input method is used, the typed text will not immediately
+   * be committed to the buffer. So if you are interested in the text,
+   * connect to this signal.
+   *
+   * Since: 2.20
+   */
+  signals[PREEDIT_CHANGED] =
+    g_signal_new_class_handler (I_("preedit-changed"),
+                                G_OBJECT_CLASS_TYPE (gobject_class),
+                                G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+                                NULL,
+                                NULL, NULL,
+                                _gtk_marshal_VOID__STRING,
+                                G_TYPE_NONE, 1,
+                                G_TYPE_STRING);
+
 
   /*
    * Key bindings
@@ -5154,6 +5176,7 @@ gtk_entry_preedit_changed_cb (GtkIMContext *context,
       gtk_im_context_get_preedit_string (entry->im_context,
                                          &preedit_string, NULL,
                                          &cursor_pos);
+      g_signal_emit (entry, signals[PREEDIT_CHANGED], 0, preedit_string);
       entry->preedit_length = strlen (preedit_string);
       cursor_pos = CLAMP (cursor_pos, 0, g_utf8_strlen (preedit_string, -1));
       entry->preedit_cursor = cursor_pos;
diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c
index 8f03ba0..80d356d 100644
--- a/gtk/gtktextview.c
+++ b/gtk/gtktextview.c
@@ -138,6 +138,7 @@ enum
   MOVE_VIEWPORT,
   SELECT_ALL,
   TOGGLE_CURSOR_VISIBLE,
+  PREEDIT_CHANGED,
   LAST_SIGNAL
 };
 
@@ -1047,6 +1048,30 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
                                 _gtk_marshal_VOID__VOID,
                                 G_TYPE_NONE, 0);
 
+  /**
+   * GtkTextView::preedit-changed:
+   * @text_view: the object which received the signal
+   * @preedit: the current preedit string
+   *
+   * If an input method is used, the typed text will not immediately
+   * be committed to the buffer. So if you are interested in the text,
+   * connect to this signal.
+   *
+   * This signal is only emitted if the text at the given position
+   * is actually editable.
+   *
+   * Since: 2.20
+   */
+  signals[PREEDIT_CHANGED] =
+    g_signal_new_class_handler (I_("preedit-changed"),
+                                G_OBJECT_CLASS_TYPE (object_class),
+                                G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+                                NULL,
+                                NULL, NULL,
+                                _gtk_marshal_VOID__STRING,
+                                G_TYPE_NONE, 1,
+                                G_TYPE_STRING);
+
   /*
    * Key bindings
    */
@@ -7373,6 +7398,8 @@ gtk_text_view_preedit_changed_handler (GtkIMContext *context,
       goto out;
     }
 
+  g_signal_emit (text_view, signals[PREEDIT_CHANGED], 0, str);
+
   if (text_view->layout)
     gtk_text_layout_set_preedit_string (text_view->layout, str, attrs, cursor_pos);
   if (GTK_WIDGET_HAS_FOCUS (text_view))
