diff --git a/dat.h b/dat.h index cd9fa82..6db751f 100644 --- a/dat.h +++ b/dat.h @@ -118,12 +118,23 @@ struct Im }; typedef struct Drawcmd Drawcmd; +typedef struct Caret Caret; +struct Caret +{ + int valid; + int x; + int y; + int w; + int h; +}; + struct Drawcmd { Str pre; Str kouho[Maxdisp]; int nkouho; int sel; + Caret caret; }; typedef struct Keyreq Keyreq; @@ -133,6 +144,7 @@ enum Keypress, Keyreset, Keyrelease, + Keycaret, }; struct Keyres { @@ -147,6 +159,7 @@ struct Keyreq int op; u32int ks; u32int mod; + Caret caret; int want; /* nonzero: include preedit in reply */ Channel *reply; }; diff --git a/ibus.c b/ibus.c index b74ba0d..82c4901 100644 --- a/ibus.c +++ b/ibus.c @@ -213,6 +213,7 @@ sendkey(u32int ks, u32int mod, Keyres *res) { Keyreq kr; + memset(&kr, 0, sizeof kr); kr.owner = owner; kr.op = Keypress; kr.ks = ks; diff --git a/srv.c b/srv.c index 72c80ae..1148fce 100644 --- a/srv.c +++ b/srv.c @@ -25,6 +25,7 @@ srvreadkey(int fd, Keyreq *kr) kr->ks = ks; kr->mod = mod; kr->want = want; + memset(&kr->caret, 0, sizeof kr->caret); return 0; } diff --git a/strans.c b/strans.c index 21a1be3..032e7f3 100644 --- a/strans.c +++ b/strans.c @@ -7,6 +7,7 @@ static int visible = 0; static Lock ownerlock; static uvlong ownerctr; static uvlong activeowner; +static Caret caret; static void dictqmap(Im*); static void dictqjp(Im*); static void backjp(Im*); @@ -128,6 +129,7 @@ show(void) if(n > Maxdisp) n = Maxdisp; dc.nkouho = n; dc.sel = im.sel >= 0 ? im.sel - first : -1; + dc.caret = caret; for(i = 0; i < n; i++) dc.kouho[i] = im.kouho[first + i]; if(dc.pre.n == 0 && n == 0 && !visible) @@ -147,6 +149,7 @@ reset(void) search.on = 0; sclear(&search.raw); sclear(&search.text); + memset(&caret, 0, sizeof caret); clearkouho(); show(); } @@ -734,6 +737,7 @@ init(void) memset(&im, 0, sizeof(im)); im.l = getlang(LangEN); memset(&search, 0, sizeof search); + memset(&caret, 0, sizeof caret); activeowner = 0; visible = 0; } @@ -763,13 +767,21 @@ imhandlekey(Keyreq *kr) if(kr->owner == activeowner) reset(); break; + case Keycaret: + if(kr->owner == activeowner){ + caret = kr->caret; + show(); + } + break; default: res.eaten = 0; if(meaningful(kr)){ if(kr->owner != activeowner){ reset(); activeowner = kr->owner; - } + caret = kr->caret; + }else if(kr->caret.valid) + caret = kr->caret; res.eaten = keystroke(kr->ks, kr->mod, &res.commit); } break; diff --git a/tests/engine_test.c b/tests/engine_test.c index a48e0fa..f69a05b 100644 --- a/tests/engine_test.c +++ b/tests/engine_test.c @@ -156,7 +156,7 @@ engine_dictionary_queue_latest_wins(struct ct *t) } static Keyres -ownerrequest(uvlong owner, int op, Rune key, u32int mod) +ownerrequestat(uvlong owner, int op, Rune key, u32int mod, Caret *caret) { Channel *reply; Keyreq req; @@ -168,6 +168,8 @@ ownerrequest(uvlong owner, int op, Rune key, u32int mod) req.op = op; req.ks = key; req.mod = mod; + if(caret != nil) + req.caret = *caret; req.want = 1; req.reply = reply; imhandlekey(&req); @@ -176,6 +178,12 @@ ownerrequest(uvlong owner, int op, Rune key, u32int mod) return res; } +static Keyres +ownerrequest(uvlong owner, int op, Rune key, u32int mod) +{ + return ownerrequestat(owner, op, key, mod, nil); +} + void engine_active_owner_lifecycle(struct ct *t) { @@ -224,6 +232,36 @@ engine_active_owner_lifecycle(struct ct *t) checkstr(t, "next owner first key", "k", &res.preedit); } +void +engine_active_owner_caret(struct ct *t) +{ + Caret a, moved; + uvlong one, two; + + one = ownernew(); + two = ownernew(); + memset(&a, 0, sizeof a); + a.valid = 1; + a.x = 10; + a.y = 20; + a.w = 3; + a.h = 14; + moved = a; + moved.x = 80; + init(); + im.l = getlang(LangJP); + ownerrequestat(one, Keypress, 'k', 0, &a); + CT_CHECK(t, caret.valid); + CT_EQ_INT(t, 10, caret.x); + ownerrequestat(two, Keycaret, 0, 0, &moved); + CT_EQ_INT(t, 10, caret.x); + ownerrequestat(one, Keycaret, 0, 0, &moved); + CT_EQ_INT(t, 80, caret.x); + ownerrequest(two, Keypress, 'n', 0); + CT_EQ_UINT(t, two, activeowner); + CT_CHECK(t, !caret.valid); +} + void engine_commit_contract(struct ct *t) { diff --git a/tests/test.h b/tests/test.h index 70d030b..1af9a44 100644 --- a/tests/test.h +++ b/tests/test.h @@ -35,6 +35,7 @@ void engine_selects_visible_candidate(struct ct*); void engine_candidate_shortcut_modifiers(struct ct*); void engine_dictionary_queue_latest_wins(struct ct*); void engine_active_owner_lifecycle(struct ct*); +void engine_active_owner_caret(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 cd1b9c0..28dd8d4 100644 --- a/tests/unit_test.c +++ b/tests/unit_test.c @@ -84,6 +84,7 @@ static const struct ct_test tests[] = { { "engine/candidate-shortcut-modifiers", engine_candidate_shortcut_modifiers }, { "engine/dictionary-queue-latest", engine_dictionary_queue_latest_wins }, { "engine/active-owner-lifecycle", engine_active_owner_lifecycle }, + { "engine/active-owner-caret", engine_active_owner_caret }, { "engine/commit-contract", engine_commit_contract }, { "engine/language-switch-state", engine_language_switch_state }, { "engine/telex-history-bound", engine_telex_history_bound }, diff --git a/wayland.c b/wayland.c index 8f18caa..bfcdfb4 100644 --- a/wayland.c +++ b/wayland.c @@ -33,6 +33,7 @@ sendkey(u32int ks, u32int mod, Keyres *res) { Keyreq kr; + memset(&kr, 0, sizeof kr); kr.owner = owner; kr.op = Keypress; kr.ks = ks;