engine: a takeover keeps the text it took for the context it took it from
Two applications' focus events cross — ibus-daemon documents the case — so the first key of the new one can arrive before the old one says it lost focus. The engine dropped whatever that context was composing; it now keeps it and hands it back with the reset or release that follows, which every frontend already commits. Normal ordering is unchanged.
This commit is contained in:
23
strans.c
23
strans.c
@@ -3,6 +3,8 @@
|
||||
|
||||
static Im im;
|
||||
static void *activeowner;
|
||||
static void *lostowner; /* the context the engine was taken from */
|
||||
static Str lost;
|
||||
static int clientpre; /* the owner draws its own preedit */
|
||||
static Caret caret;
|
||||
static Drawcmd lastdraw;
|
||||
@@ -663,6 +665,20 @@ flush(Str *com)
|
||||
reset();
|
||||
}
|
||||
|
||||
/*
|
||||
* Focus can be lost after the next context's keys arrive, so the engine
|
||||
* changes hands with text still pending. The context it was taken from
|
||||
* gets that text back when it is next heard from.
|
||||
*/
|
||||
static void
|
||||
takelost(void *owner, Str *com)
|
||||
{
|
||||
if(owner != lostowner)
|
||||
return;
|
||||
sappend(com, &lost);
|
||||
lostowner = nil;
|
||||
}
|
||||
|
||||
/*
|
||||
* A search takes over the keys. Hanja converts the pending syllable, so
|
||||
* it becomes the query; anything else pending is committed.
|
||||
@@ -881,6 +897,7 @@ init(void)
|
||||
memset(&search, 0, sizeof search);
|
||||
memset(&caret, 0, sizeof caret);
|
||||
activeowner = nil;
|
||||
lostowner = nil;
|
||||
clientpre = 0;
|
||||
memset(&lastdraw, 0, sizeof lastdraw);
|
||||
}
|
||||
@@ -902,6 +919,7 @@ imhandlekey(Keyreq *kr)
|
||||
res.eaten = 1;
|
||||
switch(kr->op){
|
||||
case Keyrelease:
|
||||
takelost(kr->owner, &res.commit);
|
||||
if(kr->owner == activeowner){
|
||||
flush(&res.commit);
|
||||
activeowner = nil;
|
||||
@@ -909,6 +927,7 @@ imhandlekey(Keyreq *kr)
|
||||
}
|
||||
break;
|
||||
case Keyreset:
|
||||
takelost(kr->owner, &res.commit);
|
||||
if(kr->owner == activeowner)
|
||||
flush(&res.commit);
|
||||
break;
|
||||
@@ -927,7 +946,9 @@ imhandlekey(Keyreq *kr)
|
||||
clientpre = kr->clientpre;
|
||||
if(keymeaningful(kr->ks)){
|
||||
if(kr->owner != activeowner){
|
||||
reset();
|
||||
sclear(&lost);
|
||||
flush(&lost);
|
||||
lostowner = lost.n > 0 ? activeowner : nil;
|
||||
activeowner = kr->owner;
|
||||
clientpre = kr->clientpre;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user