--- a/gtkhtml/gtkhtml-private.h
+++ a/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;
--- a/gtkhtml/gtkhtml.c
+++ a/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);