ibus: honor preedit and private-input policy

This commit is contained in:
2026-08-14 19:41:07 +09:00
parent 4cac6f1a15
commit a841894015
5 changed files with 482 additions and 18 deletions

View File

@@ -238,7 +238,8 @@ nexttrace(struct ct *t, Ibusfix *f, int op, Ictx *ctx)
return req;
CT_EQ_INT(t, op, req.op);
CT_EQ_PTR(t, ctx, req.owner);
CT_EQ_INT(t, Cclientpreedit, req.cap);
if(ctx != nil)
CT_EQ_INT(t, ctx->cap & 1 ? Cclientpreedit : 0, req.cap);
CT_EQ_PTR(t, replyc, req.reply);
return req;
}
@@ -282,6 +283,102 @@ contextkey(struct ct *t, Ibusfix *f, Ictx *ctx, u32int sym, u32int state)
return res;
}
void
ibus_capability_policy(struct ct *t)
{
Ibusfix f;
Ictx *a, *b;
Keyres res;
if(!ibusbegin(t, &f))
goto cleanup;
a = newcontext(f.c1, "/context/cap-a");
b = newcontext(f.c2, "/context/cap-b");
if(!CT_CHECK(t, a != nil && b != nil))
goto cleanup;
CT_EQ_INT(t, 0, a->cap);
a->focused = 1;
res = contextkey(t, &f, a, 'n', Testctrlmask);
CT_CHECK(t, res.eaten);
res = contextkey(t, &f, a, 'k', 0);
checkpreedit(t, "k", &res);
CT_EQ_PTR(t, a, testengineowner());
a->cap = Cclientpreedit;
memset(&res, 0, sizeof res);
sendrequest(a, Keycap, 0, 0, &res);
nexttrace(t, &f, Keycap, a);
CT_CHECK(t, res.eaten);
checkpreedit(t, "k", &res);
b->focused = 1;
b->cap = Cclientpreedit;
memset(&res, 0, sizeof res);
sendrequest(b, Keycap, 0, 0, &res);
nexttrace(t, &f, Keycap, b);
CT_CHECK(t, !res.eaten);
CT_EQ_PTR(t, a, testengineowner());
checkenginepreedit(t, "k");
a->cap = 0;
memset(&res, 0, sizeof res);
sendrequest(a, Keycap, 0, 0, &res);
nexttrace(t, &f, Keycap, a);
CT_CHECK(t, res.eaten);
checkpreedit(t, "k", &res);
cleanup:
ibusend(&f);
}
void
ibus_private_input_policy(struct ct *t)
{
static const struct { u32int purpose, hints; int want; } cases[] = {
{ 0, 0, 0 },
{ Ibuspurposepassword, 0, 1 },
{ Ibuspurposepin, 0, 1 },
{ 0, 1<<11, 0 },
{ 0, Ibushinthidden, 1 },
{ 37, 1<<20, 0 },
};
Ibusfix f;
Ictx *ctx;
Keyres res;
int i;
if(!ibusbegin(t, &f))
goto cleanup;
ctx = newcontext(f.c1, "/context/private");
if(!CT_CHECK(t, ctx != nil))
goto cleanup;
for(i = 0; i < nelem(cases); i++){
ctx->purpose = cases[i].purpose;
ctx->hints = cases[i].hints;
CT_EQ_INT(t, cases[i].want, hidden(ctx));
}
ctx->focused = 1;
ctx->cap = Cclientpreedit;
ctx->purpose = 0;
ctx->hints = 0;
contextkey(t, &f, ctx, 'n', Testctrlmask);
res = contextkey(t, &f, ctx, 'k', 0);
checkpreedit(t, "k", &res);
ctx->purpose = Ibuspurposepassword;
memset(&res, 0, sizeof res);
CT_CHECK(t, !processkey(ctx, 'x', 0, &res));
CT_CHECK(t, !res.eaten);
notrace(t, &f);
checkenginepreedit(t, "k");
ctx->purpose = 0;
ctx->hints = 1<<11;
res = contextkey(t, &f, ctx, 'a', 0);
checkpreedit(t, "", &res);
cleanup:
ibusend(&f);
}
void
ibus_context_lifecycle(struct ct *t)
{
@@ -307,7 +404,7 @@ ibus_context_lifecycle(struct ct *t)
notrace(t, &f);
CT_EQ_PTR(t, nil, testengineowner());
setcursor(a, 10, 20, 14);
setcursor(a, -10, -20, 14);
notrace(t, &f);
CT_CHECK(t, a->caret.valid);
a->focused = 1;
@@ -322,14 +419,14 @@ ibus_context_lifecycle(struct ct *t)
req = nexttrace(t, &f, Keypress, a);
CT_CHECK(t, !res.eaten);
CT_CHECK(t, req.caret.valid);
CT_EQ_INT(t, 10, req.caret.x);
CT_EQ_INT(t, 20, req.caret.y);
CT_EQ_INT(t, -10, req.caret.x);
CT_EQ_INT(t, -20, req.caret.y);
CT_EQ_INT(t, 14, req.caret.h);
CT_EQ_PTR(t, a, testengineowner());
testenginecaret(&at);
CT_CHECK(t, at.valid);
CT_EQ_INT(t, 10, at.x);
CT_EQ_INT(t, 20, at.y);
CT_EQ_INT(t, -10, at.x);
CT_EQ_INT(t, -20, at.y);
res = contextkey(t, &f, a, 'n', Testctrlmask);
CT_CHECK(t, res.eaten);
contextkey(t, &f, a, 'k', 0);