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:
21
xim/xim.c
21
xim/xim.c
@@ -311,23 +311,31 @@ keypress(Ic *state, u32int key, u32int mod, Keyres *res)
|
||||
sendrequest(state, Keypress, key, mod, res);
|
||||
}
|
||||
|
||||
/* Losing the engine commits the pending text; the release hands it back. */
|
||||
static void
|
||||
release(Ic *state)
|
||||
{
|
||||
Keyres res;
|
||||
char buf[Maxutf];
|
||||
int n;
|
||||
|
||||
clearpreedit(state);
|
||||
if(!state->engaged)
|
||||
if(!state->engaged){
|
||||
clearpreedit(state);
|
||||
return;
|
||||
}
|
||||
sendrequest(state, Keyrelease, 0, 0, &res);
|
||||
state->engaged = 0;
|
||||
n = stoutf(&res.commit, buf, sizeof buf);
|
||||
commit(state, buf, n);
|
||||
clearpreedit(state);
|
||||
xcb_flush(conn);
|
||||
}
|
||||
|
||||
/* XIM reset hands the pending preedit back to the client as committed text. */
|
||||
/* XIM reset hands the pending text back to the client as committed text. */
|
||||
static void
|
||||
resetic(Ic *state, xcb_im_reset_ic_reply_fr_t *reply)
|
||||
{
|
||||
Keyres pending, res;
|
||||
Keyres res;
|
||||
char utf[Maxutf], *wire;
|
||||
size_t nwire;
|
||||
int nbyte;
|
||||
@@ -336,12 +344,11 @@ resetic(Ic *state, xcb_im_reset_ic_reply_fr_t *reply)
|
||||
clearpreedit(state);
|
||||
return;
|
||||
}
|
||||
sendrequest(state, Keycap, 0, 0, &pending);
|
||||
sendrequest(state, Keyreset, 0, 0, &res);
|
||||
clearpreedit(state);
|
||||
if(reply == nil || !pending.eaten || pending.preedit.n == 0)
|
||||
if(reply == nil || res.commit.n == 0)
|
||||
return;
|
||||
nbyte = stoutf(&pending.preedit, utf, sizeof utf);
|
||||
nbyte = stoutf(&res.commit, utf, sizeof utf);
|
||||
wire = xcb_utf8_to_compound_text(utf, nbyte, &nwire);
|
||||
if(wire == nil)
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user