fix: retain the newest dictionary request

This commit is contained in:
2026-08-12 15:37:50 +09:00
parent fabce14933
commit 9c244d1dd1
4 changed files with 57 additions and 7 deletions

View File

@@ -135,7 +135,7 @@ reset(void)
void
dictsend(Im *im, Str *key)
{
Dictreq req;
Dictreq old, req;
req.key = *key;
req.lang = im->l->lang;
@@ -143,6 +143,9 @@ dictsend(Im *im, Str *key)
jpreading(im, &req.pre);
else
req.pre = im->pre;
/* imthread is the sole producer; discard every obsolete queued lookup. */
while(channbrecv(dictreqc, &old) > 0)
;
channbsend(dictreqc, &req);
}
@@ -271,7 +274,6 @@ static int
dotrans(Rune c, Str *com)
{
Emit e;
Dictreq req;
Str mapped;
if(isjp(&im))
@@ -297,10 +299,7 @@ dotrans(Rune c, Str *com)
sclear(&im.pre);
sappend(&im.pre, &e.next);
if(e.eat && e.dict.n > 0){
req.key = e.dict;
req.lang = im.l->lang;
req.pre = im.pre;
channbsend(dictreqc, &req);
dictsend(&im, &e.dict);
}
return e.eat;
}
@@ -626,7 +625,7 @@ keystroke(u32int ks, u32int mod, Str *com)
off = 0;
if(im.sel >= Maxdisp)
off = im.sel - Maxdisp + 1;
if(n >= 0 && n < Maxdisp && off + n < im.nkouho){
if(n >= 0 && n < Maxdisp && off + n < im.nkouho && mod == 0){
sappend(com, &im.kouho[off + n]);
reset();
return 1;

View File

@@ -108,6 +108,53 @@ engine_selects_visible_candidate(struct ct *t)
}
}
void
engine_candidate_shortcut_modifiers(struct ct *t)
{
static u32int mods[] = { Mctrl, Malt, Msuper };
Str com;
int i;
for(i = 0; i < nelem(mods); i++){
init();
im.kouho[0] = mkstr("must-not-select");
im.nkouho = 1;
im.sel = -1;
sclear(&com);
CT_CHECK(t, !keystroke('1', mods[i], &com));
CT_CHECK(t, scmp(&com, &im.kouho[0]) != 0);
}
}
void
engine_dictionary_queue_latest_wins(struct ct *t)
{
Channel *saved;
Dictreq old, got;
Str key;
saved = dictreqc;
dictreqc = chancreate(sizeof(Dictreq), 1);
memset(&old, 0, sizeof old);
old.key = mkstr("old-key");
old.pre = mkstr("old-preedit");
old.lang = LangJP;
CT_CHECK(t, channbsend(dictreqc, &old) > 0);
init();
im.l = getlang(LangJP);
im.pre = mkstr("new-preedit");
key = mkstr("new-key");
dictsend(&im, &key);
if(CT_CHECK(t, channbrecv(dictreqc, &got) > 0)){
checkstr(t, "newest dictionary key", "new-key", &got.key);
checkstr(t, "newest dictionary preedit", "new-preedit", &got.pre);
CT_EQ_INT(t, LangJP, got.lang);
}
CT_CHECK(t, channbrecv(dictreqc, &got) <= 0);
chanfree(dictreqc);
dictreqc = saved;
}
void
engine_commit_contract(struct ct *t)
{

View File

@@ -32,6 +32,8 @@ void vietnamese_state_lifetime(struct ct*);
void engine_clears_candidates(struct ct*);
void engine_backspace_clears_candidates(struct ct*);
void engine_selects_visible_candidate(struct ct*);
void engine_candidate_shortcut_modifiers(struct ct*);
void engine_dictionary_queue_latest_wins(struct ct*);
void engine_commit_contract(struct ct*);
void engine_language_switch_state(struct ct*);
void engine_telex_history_bound(struct ct*);

View File

@@ -81,6 +81,8 @@ static const struct ct_test tests[] = {
{ "engine/clears-candidates", engine_clears_candidates },
{ "engine/backspace-clears-candidates", engine_backspace_clears_candidates },
{ "engine/selects-visible-candidate", engine_selects_visible_candidate },
{ "engine/candidate-shortcut-modifiers", engine_candidate_shortcut_modifiers },
{ "engine/dictionary-queue-latest", engine_dictionary_queue_latest_wins },
{ "engine/commit-contract", engine_commit_contract },
{ "engine/language-switch-state", engine_language_switch_state },
{ "engine/telex-history-bound", engine_telex_history_bound },