fix(engine): a reset or a lost focus commits the pending text
Clicking elsewhere, changing focus, or any client reset dropped the composition in the GTK module and IBus (only XIM ResetIC handed it back), so typing 안녕 and clicking Send lost 녕. The engine now returns the pending text — a moved-to candidate first, as Enter would — on Keyreset and Keyrelease; the GTK module asks for it before closing on focus-out and commits it, IBus commits it on FocusOut, Reset and a switch to a password field, and XIM commits it on focus loss and hands it back on ResetIC without a separate capability probe.
This commit is contained in:
41
strans.c
41
strans.c
@@ -572,6 +572,22 @@ startsearch(int lang, Str *com)
|
||||
search.lang = lang;
|
||||
}
|
||||
|
||||
/*
|
||||
* Whatever is pending becomes committed text, a moved-to candidate
|
||||
* first: Enter does this, and so do a reset and a lost focus.
|
||||
*/
|
||||
static void
|
||||
flush(Str *com)
|
||||
{
|
||||
if(search.lang)
|
||||
commitsearch(com);
|
||||
else if(candidatechosen && im.sel >= 0 && im.sel < im.nkouho)
|
||||
sappend(com, &im.kouho[im.sel]);
|
||||
else
|
||||
commit(com);
|
||||
reset();
|
||||
}
|
||||
|
||||
static void
|
||||
picksearch(int n, Str *com)
|
||||
{
|
||||
@@ -679,17 +695,10 @@ transition(u32int ks, u32int mod, Str *com)
|
||||
return 1;
|
||||
}
|
||||
if(ks == Ktab || ks == Kret){
|
||||
if(candidatechosen && im.sel >= 0 && im.sel < im.nkouho){
|
||||
sappend(com, &im.kouho[im.sel]);
|
||||
reset();
|
||||
return 1;
|
||||
}
|
||||
if(haspre(&im)){
|
||||
commit(com);
|
||||
reset();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
if(!haspre(&im))
|
||||
return 0;
|
||||
flush(com);
|
||||
return 1;
|
||||
}
|
||||
if(ks == Kback){
|
||||
if(!haspre(&im))
|
||||
@@ -773,8 +782,10 @@ init(void)
|
||||
|
||||
/*
|
||||
* The engine belongs to whichever context last typed a real key; only
|
||||
* the owner's requests change state. Every request ends in redraw(),
|
||||
* which sends the popup a picture only if something visible changed.
|
||||
* the owner's requests change state. A reset or release hands the
|
||||
* owner its pending text back as commit. Every request ends in
|
||||
* redraw(), which sends the popup a picture only if something visible
|
||||
* changed.
|
||||
*/
|
||||
static void
|
||||
imhandlekey(Keyreq *kr)
|
||||
@@ -787,14 +798,14 @@ imhandlekey(Keyreq *kr)
|
||||
switch(kr->op){
|
||||
case Keyrelease:
|
||||
if(kr->owner == activeowner){
|
||||
reset();
|
||||
flush(&res.commit);
|
||||
activeowner = nil;
|
||||
activecap = 0;
|
||||
}
|
||||
break;
|
||||
case Keyreset:
|
||||
if(kr->owner == activeowner)
|
||||
reset();
|
||||
flush(&res.commit);
|
||||
break;
|
||||
case Keycaret:
|
||||
if(kr->owner == activeowner)
|
||||
|
||||
Reference in New Issue
Block a user