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]);
|
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
|
static int
|
||||||
processkey(Ictx *ctx, u32int sym, u32int state, Keyres *res)
|
processkey(Ictx *ctx, u32int sym, u32int state, Keyres *res)
|
||||||
{
|
{
|
||||||
if(state & Relmask || !ctx->focused || hidden(ctx))
|
if(state & Relmask || hidden(ctx))
|
||||||
return 0;
|
return 0;
|
||||||
|
ctx->focused = 1;
|
||||||
sendrequest(ctx, Keypress, ipckeysym(sym, xkb_keysym_to_utf32(sym)),
|
sendrequest(ctx, Keypress, ipckeysym(sym, xkb_keysym_to_utf32(sym)),
|
||||||
ipcmod(state), res);
|
ipcmod(state), res);
|
||||||
if(preowner != nil && preowner != ctx)
|
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, b, findcontext(f.c2, "/context/one"));
|
||||||
CT_EQ_PTR(t, nil, findcontext(f.c1, "/context/missing"));
|
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);
|
setcursor(a, -10, -20, 14);
|
||||||
notrace(t, &f);
|
notrace(t, &f);
|
||||||
CT_CHECK(t, a->caret.valid);
|
CT_CHECK(t, a->caret.valid);
|
||||||
a->focused = 1;
|
|
||||||
memset(&res, 0, sizeof res);
|
memset(&res, 0, sizeof res);
|
||||||
CT_CHECK(t, !processkey(a, 'x', Relmask, &res));
|
CT_CHECK(t, !processkey(a, 'x', Relmask, &res));
|
||||||
CT_CHECK(t, !res.eaten);
|
CT_CHECK(t, !res.eaten);
|
||||||
notrace(t, &f);
|
notrace(t, &f);
|
||||||
|
CT_CHECK(t, !a->focused);
|
||||||
CT_EQ_PTR(t, nil, testengineowner());
|
CT_EQ_PTR(t, nil, testengineowner());
|
||||||
|
|
||||||
|
/* A key stands for the FocusIn a client may never send. */
|
||||||
memset(&res, 0, sizeof res);
|
memset(&res, 0, sizeof res);
|
||||||
CT_CHECK(t, processkey(a, 'x', 0, &res));
|
CT_CHECK(t, processkey(a, 'x', 0, &res));
|
||||||
req = nexttrace(t, &f, Keypress, a);
|
req = nexttrace(t, &f, Keypress, a);
|
||||||
|
CT_CHECK(t, a->focused);
|
||||||
CT_CHECK(t, !res.eaten);
|
CT_CHECK(t, !res.eaten);
|
||||||
CT_CHECK(t, req.caret.valid);
|
CT_CHECK(t, req.caret.valid);
|
||||||
CT_EQ_INT(t, -10, req.caret.x);
|
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");
|
reused = newcontext(f.c1, "/context/prune");
|
||||||
CT_EQ_PTR(t, ctx, reused);
|
CT_EQ_PTR(t, ctx, reused);
|
||||||
CT_EQ_PTR(t, nil, testengineowner());
|
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);
|
contextkey(t, &f, reused, 'n', 0);
|
||||||
|
CT_CHECK(t, reused->focused);
|
||||||
CT_EQ_PTR(t, reused, testengineowner());
|
CT_EQ_PTR(t, reused, testengineowner());
|
||||||
dropconncontexts(f.c1);
|
dropconncontexts(f.c1);
|
||||||
nexttrace(t, &f, Keyrelease, reused);
|
nexttrace(t, &f, Keyrelease, reused);
|
||||||
|
|||||||
Reference in New Issue
Block a user