diff --git a/strans.c b/strans.c index 5ac1018..73681ad 100644 --- a/strans.c +++ b/strans.c @@ -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; diff --git a/tests/engine_test.c b/tests/engine_test.c index 744fb1f..de8ad76 100644 --- a/tests/engine_test.c +++ b/tests/engine_test.c @@ -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) { diff --git a/tests/test.h b/tests/test.h index a16b451..db0519a 100644 --- a/tests/test.h +++ b/tests/test.h @@ -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*); diff --git a/tests/unit_test.c b/tests/unit_test.c index aecefc8..b101aa0 100644 --- a/tests/unit_test.c +++ b/tests/unit_test.c @@ -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 },