engine: update active preedit capability

This commit is contained in:
2026-08-14 18:44:52 +09:00
parent 9a3a92170e
commit b536573622
3 changed files with 68 additions and 18 deletions

3
dat.h
View File

@@ -147,10 +147,11 @@ enum
Keyreset, Keyreset,
Keyrelease, Keyrelease,
Keycaret, Keycaret,
Keycap,
}; };
struct Keyres struct Keyres
{ {
int eaten; int eaten; /* Keycap: caller is active and capability was applied. */
Str commit; Str commit;
Str preedit; Str preedit;
}; };

View File

@@ -783,6 +783,17 @@ meaningful(Keyreq *kr)
return kr->ks != 0 && !ismodkey(kr->ks); return kr->ks != 0 && !ismodkey(kr->ks);
} }
static int
setactivecap(int cap)
{
int old;
old = activecap & Cclientpreedit;
activecap &= ~Cclientpreedit;
activecap |= cap & Cclientpreedit;
return old != (activecap & Cclientpreedit);
}
static void static void
imhandlekey(Keyreq *kr) imhandlekey(Keyreq *kr)
{ {
@@ -809,13 +820,24 @@ imhandlekey(Keyreq *kr)
show(); show();
} }
break; break;
case Keycap:
res.eaten = 0;
if(activeowner != nil && kr->owner == activeowner){
res.eaten = 1;
if(setactivecap(kr->cap))
show();
}
break;
case Keypress: case Keypress:
res.eaten = 0; res.eaten = 0;
if(activeowner != nil && kr->owner == activeowner &&
setactivecap(kr->cap))
show();
if(meaningful(kr)){ if(meaningful(kr)){
if(kr->owner != activeowner){ if(kr->owner != activeowner){
reset(); reset();
activeowner = kr->owner; activeowner = kr->owner;
activecap = kr->cap; activecap = kr->cap & Cclientpreedit;
caret = kr->caret; caret = kr->caret;
}else if(kr->caret.valid) }else if(kr->caret.valid)
caret = kr->caret; caret = kr->caret;

View File

@@ -728,7 +728,8 @@ engine_popup_preedit_capability(struct ct *t)
{ {
Dictres res; Dictres res;
Drawcmd dc; Drawcmd dc;
char client, popupowner; Keyres kres;
char client, inactive;
init(); init();
im.l = getlang(LangJP); im.l = getlang(LangJP);
@@ -742,30 +743,56 @@ engine_popup_preedit_capability(struct ct *t)
res.kouho[0] = mkstr(""); res.kouho[0] = mkstr("");
res.nkouho = 1; res.nkouho = 1;
dictresult(&res); dictresult(&res);
im.sel = 0;
show();
if(CT_CHECK(t, draindraw(&dc) > 0)){ if(CT_CHECK(t, draindraw(&dc) > 0)){
CT_EQ_INT(t, 0, dc.pre.n); CT_EQ_INT(t, 0, dc.pre.n);
CT_EQ_INT(t, 1, dc.nkouho); CT_EQ_INT(t, 1, dc.nkouho);
CT_EQ_INT(t, 0, dc.sel);
checkstr(t, "client-preedit candidate", "", &dc.kouho[0]); checkstr(t, "client-preedit candidate", "", &dc.kouho[0]);
} }
ownerrequestcap(&popupowner, 0, Keypress, 'n', 0); kres = ownerrequestcap(&client, 0, Keycap, 0, 0);
CT_CHECK(t, kres.eaten);
checkstr(t, "capability response preedit", "", &kres.preedit);
if(CT_CHECK(t, draindraw(&dc) > 0)){ if(CT_CHECK(t, draindraw(&dc) > 0)){
checkstr(t, "popup preedit", "", &dc.pre); checkstr(t, "popup preedit", "", &dc.pre);
CT_EQ_INT(t, 0, dc.nkouho);
}
memset(&res, 0, sizeof res);
res.lang = LangJP;
res.key = mkstr("");
res.seq = dictseq;
res.kouho[0] = mkstr("");
res.nkouho = 1;
dictresult(&res);
if(CT_CHECK(t, draindraw(&dc) > 0)){
checkstr(t, "async popup preedit", "", &dc.pre);
CT_EQ_INT(t, 1, dc.nkouho); CT_EQ_INT(t, 1, dc.nkouho);
checkstr(t, "popup candidate", "", &dc.kouho[0]); CT_EQ_INT(t, 0, dc.sel);
checkstr(t, "popup candidate", "", &dc.kouho[0]);
} }
ownerrequest(&popupowner, Keyrelease, 0, 0); CT_EQ_INT(t, 1, im.nkouho);
CT_EQ_INT(t, 0, im.sel);
checkstr(t, "retained popup candidate", "", &im.kouho[0]);
kres = ownerrequestcap(&client, 0, Keycap, 0, 0);
CT_CHECK(t, kres.eaten);
CT_EQ_INT(t, 0, draindraw(nil));
kres = ownerrequestcap(&inactive, Cclientpreedit, Keycap, 0, 0);
CT_CHECK(t, !kres.eaten);
CT_EQ_INT(t, 0, kres.preedit.n);
CT_EQ_PTR(t, &client, activeowner);
CT_EQ_INT(t, 0, activecap & Cclientpreedit);
CT_EQ_INT(t, 0, draindraw(nil));
kres = ownerrequestcap(&client, Cclientpreedit, Keycap, 0, 0);
CT_CHECK(t, kres.eaten);
checkstr(t, "restored client preedit", "", &kres.preedit);
if(CT_CHECK(t, draindraw(&dc) > 0)){
CT_EQ_INT(t, 0, dc.pre.n);
CT_EQ_INT(t, 1, dc.nkouho);
CT_EQ_INT(t, 0, dc.sel);
checkstr(t, "restored client candidate", "", &dc.kouho[0]);
}
CT_EQ_INT(t, 1, im.nkouho);
CT_EQ_INT(t, 0, im.sel);
checkstr(t, "retained client candidate", "", &im.kouho[0]);
kres = ownerrequestcap(&client, Cclientpreedit, Keycap, 0, 0);
CT_CHECK(t, kres.eaten);
CT_EQ_INT(t, 0, draindraw(nil));
ownerrequest(&client, Keyrelease, 0, 0);
draindraw(nil); draindraw(nil);
} }