fix(engine): redraw only for visible caret changes

This commit is contained in:
2026-08-15 15:07:13 +09:00
parent f489c56fb1
commit 67ed2ef478
2 changed files with 40 additions and 7 deletions

View File

@@ -925,6 +925,13 @@ setactivecap(int cap)
return old != (activecap & Cclientpreedit);
}
static int
careteq(Caret *a, Caret *b)
{
return a->valid == b->valid && a->x == b->x && a->y == b->y &&
a->h == b->h;
}
static void
imhandlekey(Keyreq *kr)
{
@@ -952,8 +959,9 @@ imhandlekey(Keyreq *kr)
}
break;
case Keycaret:
if(kr->owner == activeowner){
if(kr->owner == activeowner && !careteq(&caret, &kr->caret)){
caret = kr->caret;
if(visible)
redraw();
}
break;
@@ -978,7 +986,8 @@ imhandlekey(Keyreq *kr)
activecap = kr->cap & Cclientpreedit;
caret = kr->caret;
changed = 1;
}else if(kr->caret.valid){
}else if(kr->caret.valid &&
!careteq(&caret, &kr->caret)){
caret = kr->caret;
changed = 1;
}

View File

@@ -370,6 +370,7 @@ void
engine_active_owner_caret(struct ct *t)
{
Caret a, moved;
Drawcmd dc;
char one, two;
memset(&a, 0, sizeof a);
@@ -380,14 +381,37 @@ engine_active_owner_caret(struct ct *t)
moved = a;
moved.x = 80;
init();
im.l = getlang(LangJP);
ownerrequestat(&one, Keypress, 'k', 0, &a);
draindraw(nil);
im.l = getlang(LangEN);
ownerrequestat(&one, Keypress, 'x', 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);
CT_EQ_INT(t, 0, draindraw(nil));
im.kouho[0] = mkstr("candidate");
im.nkouho = 1;
im.sel = 0;
redraw();
if(CT_CHECK(t, draindraw(&dc) > 0))
CT_EQ_INT(t, 80, dc.caret.x);
moved.x = 90;
ownerrequestat(&two, Keycaret, 0, 0, &moved);
CT_EQ_INT(t, 80, caret.x);
CT_EQ_INT(t, 0, draindraw(nil));
ownerrequestat(&one, Keycaret, 0, 0, &moved);
CT_EQ_INT(t, 90, caret.x);
if(CT_CHECK(t, draindraw(&dc) > 0))
CT_EQ_INT(t, 90, dc.caret.x);
ownerrequestat(&one, Keycaret, 0, 0, &moved);
CT_EQ_INT(t, 0, draindraw(nil));
ownerrequestat(&one, Keypress, 'x', 0, &moved);
CT_EQ_INT(t, 0, draindraw(nil));
moved.x = 100;
ownerrequestat(&one, Keypress, 'x', 0, &moved);
CT_EQ_INT(t, 100, caret.x);
if(CT_CHECK(t, draindraw(&dc) > 0))
CT_EQ_INT(t, 100, dc.caret.x);
ownerrequest(&two, Keypress, 'n', 0);
CT_EQ_PTR(t, &two, activeowner);
CT_CHECK(t, !caret.valid);