ibus: a key stands for the FocusIn a client may never send
A context that had not sent FocusIn had every key rejected outright, so the input method was silently dead in a client that omits or delays it, and in the documented case of two applications whose focus events cross. ibus-daemon and fcitx5 both treat a key as focus; strans, which plays the daemon here, now does too. A release still does not focus, and the engine's own owner rule is unchanged.
This commit is contained in:
7
ibus.c
7
ibus.c
@@ -526,11 +526,16 @@ dropconncontexts(DBusConnection *conn)
|
||||
dropcontext(&contexts[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
* A key is proof of focus: some clients never send FocusIn, and the
|
||||
* focus events of two applications can cross.
|
||||
*/
|
||||
static int
|
||||
processkey(Ictx *ctx, u32int sym, u32int state, Keyres *res)
|
||||
{
|
||||
if(state & Relmask || !ctx->focused || hidden(ctx))
|
||||
if(state & Relmask || hidden(ctx))
|
||||
return 0;
|
||||
ctx->focused = 1;
|
||||
sendrequest(ctx, Keypress, ipckeysym(sym, xkb_keysym_to_utf32(sym)),
|
||||
ipcmod(state), res);
|
||||
if(preowner != nil && preowner != ctx)
|
||||
|
||||
@@ -281,25 +281,21 @@ ibus_context_lifecycle(struct ct *t)
|
||||
CT_EQ_PTR(t, b, findcontext(f.c2, "/context/one"));
|
||||
CT_EQ_PTR(t, nil, findcontext(f.c1, "/context/missing"));
|
||||
|
||||
memset(&res, 0, sizeof res);
|
||||
CT_CHECK(t, !processkey(a, 'x', 0, &res));
|
||||
CT_CHECK(t, !res.eaten);
|
||||
notrace(t, &f);
|
||||
CT_EQ_PTR(t, nil, testengineowner());
|
||||
|
||||
setcursor(a, -10, -20, 14);
|
||||
notrace(t, &f);
|
||||
CT_CHECK(t, a->caret.valid);
|
||||
a->focused = 1;
|
||||
memset(&res, 0, sizeof res);
|
||||
CT_CHECK(t, !processkey(a, 'x', Relmask, &res));
|
||||
CT_CHECK(t, !res.eaten);
|
||||
notrace(t, &f);
|
||||
CT_CHECK(t, !a->focused);
|
||||
CT_EQ_PTR(t, nil, testengineowner());
|
||||
|
||||
/* A key stands for the FocusIn a client may never send. */
|
||||
memset(&res, 0, sizeof res);
|
||||
CT_CHECK(t, processkey(a, 'x', 0, &res));
|
||||
req = nexttrace(t, &f, Keypress, a);
|
||||
CT_CHECK(t, a->focused);
|
||||
CT_CHECK(t, !res.eaten);
|
||||
CT_CHECK(t, req.caret.valid);
|
||||
CT_EQ_INT(t, -10, req.caret.x);
|
||||
@@ -430,12 +426,8 @@ ibus_active_release_lifecycle(struct ct *t)
|
||||
reused = newcontext(f.c1, "/context/prune");
|
||||
CT_EQ_PTR(t, ctx, reused);
|
||||
CT_EQ_PTR(t, nil, testengineowner());
|
||||
memset(&res, 0, sizeof res);
|
||||
CT_CHECK(t, !processkey(reused, 'x', 0, &res));
|
||||
CT_CHECK(t, !res.eaten);
|
||||
notrace(t, &f);
|
||||
reused->focused = 1;
|
||||
contextkey(t, &f, reused, 'n', 0);
|
||||
CT_CHECK(t, reused->focused);
|
||||
CT_EQ_PTR(t, reused, testengineowner());
|
||||
dropconncontexts(f.c1);
|
||||
nexttrace(t, &f, Keyrelease, reused);
|
||||
|
||||
Reference in New Issue
Block a user