diff --git a/gtk/main.c b/gtk/main.c index 9c15764..78dd8b1 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -252,6 +252,7 @@ kpress(GtkIMContext *ctx, GdkEventKey *ev) char pre[Ipcfieldmax+1]; uint32_t key, mod; Ipcresp resp; + gboolean r; im = (Im*)ctx; if(ev->type != GDK_KEY_PRESS){ @@ -263,8 +264,13 @@ kpress(GtkIMContext *ctx, GdkEventKey *ev) return simplefilter(ctx, ev, 0); key = ipckeysym(ev->keyval, gdk_keyval_to_unicode(ev->keyval)); mod = ipcmod(ev->state); - if(im->private || key == 0) - return simplefilter(ctx, ev, 0); + if(im->private || key == 0){ + r = simplefilter(ctx, ev, 0); + /* A dead key starts a compose: pending text was typed first. */ + if(im->simpleactive) + sendreset(im); + return r; + } if(srvconnect(im) < 0) return simplefilter(ctx, ev, 0); /* A retained GDK window may have moved since the last cursor report. */ diff --git a/tests/gtk_live_test.c b/tests/gtk_live_test.c index 7fa685d..6b54e29 100644 --- a/tests/gtk_live_test.c +++ b/tests/gtk_live_test.c @@ -764,6 +764,26 @@ main(int argc, char **argv) Check(key(ctx, win, GDK_KEY_dead_acute) && key(ctx, win, GDK_KEY_e), "dead-key sequence was not consumed"); Check(strcmp(log.commit, "é") == 0, "dead key committed %s", log.commit); + + /* A dead key over a preedit hands the pending text back first. */ + setreply(&srv, 1, Rnormal, 0); + setpre(&srv, "하"); + clearlog(&log); + Check(key(ctx, win, GDK_KEY_h), "dead-key setup key was not eaten"); + clearevent(&log); + first = eventcount(&srv); + Check(!key(ctx, win, GDK_KEY_Shift_L), "a modifier press was eaten"); + Check(eventcount(&srv) == first && strcmp(log.pre, "하") == 0, + "a modifier press disturbed the preedit"); + setreply(&srv, 0, Rnormal, 0); + setpre(&srv, ""); + Check(key(ctx, win, GDK_KEY_dead_acute) && key(ctx, win, GDK_KEY_e), + "dead key over a preedit was not consumed"); + Check(getevent(&srv, first).type == Ereset, + "dead key did not hand the pending text back"); + Check(strcmp(log.commit, "é") == 0 && log.pre[0] == '\0', + "dead key over a preedit committed %s (preedit %s)", + log.commit, log.pre); clearlog(&log); Check(keystate(ctx, win, GDK_KEY_U, GDK_CONTROL_MASK|GDK_SHIFT_MASK), "Unicode prefix was not consumed");