diff --git a/gtkhtml/gtkhtml-private.h b/gtkhtml/gtkhtml-private.h
index 5e23390..4028188 100644
--- a/gtkhtml/gtkhtml-private.h
+++ b/gtkhtml/gtkhtml-private.h
@@ -53,6 +53,7 @@ struct _GtkHTMLPrivate {
 	gint im_pre_pos;
 	GtkHTMLFontStyle im_orig_style;
 	gboolean im_block_reset;
+	gint im_cumulative_cursor_move;
 
 	HTMLObject *dnd_object;
 	gint        dnd_object_offset;
diff --git a/gtkhtml/gtkhtml.c b/gtkhtml/gtkhtml.c
index ebb908b..5b8443c 100644
--- a/gtkhtml/gtkhtml.c
+++ b/gtkhtml/gtkhtml.c
@@ -124,7 +124,7 @@ struct _ClipboardContents {
 };
 
 #define d_s(x)
-#define D_IM(x)
+#define D_IM(x) x
 
 static GtkLayoutClass *parent_class = NULL;
 
@@ -3213,6 +3213,12 @@ gtk_html_im_commit_cb (GtkIMContext *context, const gchar *str, GtkHTML *html)
                 html_undo_thaw (html->engine->undo);
         }
 
+	/* Let cursor jump back when im_preedit starts */
+	html_cursor_exactly_jump_to_position_no_spell (html->engine->cursor, html->engine,
+						       html->engine->cursor->position - 
+						       html->priv->im_cumulative_cursor_move);
+	html->priv->im_cumulative_cursor_move = 0;
+
 	pos = html->engine->cursor->position;
 	if (html->engine->mark && html->engine->mark->position > pos)
 		pos = html->engine->mark->position;
@@ -3230,6 +3236,7 @@ static void
 gtk_html_im_preedit_start_cb (GtkIMContext *context, GtkHTML *html)
 {
 	html->priv->im_pre_len = 0;
+	html->priv->im_cumulative_cursor_move = 0;
 }
 
 static void
@@ -3277,6 +3284,7 @@ gtk_html_im_preedit_changed_cb (GtkIMContext *context, GtkHTML *html)
 		html->priv->im_orig_style = html_engine_get_font_style (html->engine);
 
 	gtk_im_context_get_preedit_string (html->priv->im_context, &preedit_string, &attrs, &cursor_pos);
+	html->priv->im_cumulative_cursor_move += cursor_pos;
 
 	D_IM (printf ("IM preedit changed to %s\n", preedit_string);)
 	html->priv->im_pre_len = g_utf8_strlen (preedit_string, -1);
@@ -3450,6 +3458,7 @@ gtk_html_init (GtkHTML* html)
 	html->priv->need_im_reset = FALSE;
 	html->priv->im_block_reset = FALSE;
 	html->priv->im_pre_len = 0;
+	html->priv->im_cumulative_cursor_move = 0;
 
 	g_signal_connect (G_OBJECT (html->priv->im_context), "commit",
 			  G_CALLBACK (gtk_html_im_commit_cb), html);
