fix(frontends): preserve preedit lifecycle

This commit is contained in:
2026-08-15 15:05:49 +09:00
parent aeb6010f3c
commit d29d43f443
6 changed files with 164 additions and 46 deletions

View File

@@ -37,6 +37,7 @@ enum
enum
{
Rnormal,
Rcommitpre,
Rbadcommit,
Rbadpreedit,
};
@@ -156,7 +157,10 @@ sendresponse(Server *s, int fd, int eaten, int want, int key)
commit = "";
ncommit = 0;
npreedit = strlen(pre);
if(key && response == Rbadcommit){
if(key && response == Rcommitpre){
commit = pre;
ncommit = npreedit;
}else if(key && response == Rbadcommit){
commit = "\xc3(";
ncommit = 2;
}else if(key && response == Rbadpreedit){
@@ -581,6 +585,7 @@ commit(GtkIMContext *ctx, gchar *s, Siglog *l)
{
(void)ctx;
snprintf(l->commit, sizeof l->commit, "%s", s);
l->pre[0] = '\0';
logsig(l, 'K');
}
@@ -721,7 +726,7 @@ main(int argc, char **argv)
rect.height = 19;
gtk_im_context_set_cursor_location(ctx, &rect);
Check(eventcount(&srv) == 0, "cursor reporting opened the socket");
setpre(&srv, "pre");
setpre(&srv, "");
Check(key(ctx, win, GDK_KEY_a), "initial key was not eaten");
Check(waitcount(&srv, 3), "initial protocol frames timed out");
e = getevent(&srv, 0);
@@ -739,8 +744,22 @@ main(int argc, char **argv)
(oy + rect.y) * scale, rect.height * scale);
e = getevent(&srv, 2);
Check(e.type == Ekey && e.want == 1, "initial key framing changed");
Check(strcmp(log.event, "SC") == 0 && strcmp(log.pre, "pre") == 0,
"initial preedit signals were %s (%s)", log.event, log.pre);
Check(log.n == 0, "initial empty preedit emitted %s", log.event);
setpre(&srv, "");
clearlog(&log);
Check(key(ctx, win, GDK_KEY_z), "first preedit key was not eaten");
Check(strcmp(log.event, "SC") == 0 && strcmp(log.pre, "") == 0,
"first preedit signals were %s (%s)", log.event, log.pre);
clearlog(&log);
setreply(&srv, 1, Rcommitpre, 0);
Check(key(ctx, win, GDK_KEY_z), "repeated preedit key was not eaten");
Check(strcmp(log.event, "KC") == 0 &&
strcmp(log.commit, "") == 0 && strcmp(log.pre, "") == 0,
"repeated preedit signals were %s (commit %s, preedit %s)",
log.event, log.commit, log.pre);
Check(g_utf8_strlen(log.commit, -1) + g_utf8_strlen(log.pre, -1) == 2,
"two physical keys produced commit %s and preedit %s",
log.commit, log.pre);
/* Unconsumed input uses GtkIMContextSimple, including its stateful forms. */
setpre(&srv, "");