xim: refresh placement before each key

This commit is contained in:
2026-08-14 17:43:56 +09:00
parent 68dc1e6a18
commit 76af1a022f
2 changed files with 32 additions and 22 deletions

View File

@@ -82,7 +82,7 @@ enum
Wdraw,
Wdone,
Wcommit,
Maxwire = 64,
Maxwire = 8,
};
typedef struct Wirecall Wirecall;
@@ -108,7 +108,6 @@ struct Wirewin
xcb_window_t win;
int geometryok;
int translateok;
int samescreen;
int rootx;
int rooty;
int height;
@@ -257,7 +256,7 @@ wiretranslatereply(xcb_connection_t *c,
return nil;
reply = calloc(1, sizeof *reply);
if(reply != nil){
reply->same_screen = w->samescreen;
reply->same_screen = 1;
reply->dst_x = w->rootx + transx;
reply->dst_y = w->rooty + transy;
}
@@ -301,7 +300,6 @@ wirewin(int n, xcb_window_t win, int x, int y, int h)
w->win = win;
w->geometryok = 1;
w->translateok = 1;
w->samescreen = 1;
w->rootx = x;
w->rooty = y;
w->height = h;
@@ -629,7 +627,6 @@ xim_adapter_styles(struct ct *t)
CT_EQ_UINT(t, want[i], styles[i]);
CT_CHECK(t, stylecap(want[i], &cap));
CT_EQ_INT(t, i == 1 ? Cclientpreedit : 0, cap);
CT_CHECK(t, !(styles[i] & XCB_IM_PreeditNone));
}
CT_CHECK(t, !stylecap(XCB_IM_PreeditNone | XCB_IM_StatusNothing,
&cap));
@@ -717,14 +714,20 @@ xim_adapter_placement_updates(struct ct *t)
{
xcb_im_packet_header_fr_t hdr;
xcb_im_input_context_t *ic;
xcb_key_press_event_t ev;
Icbinding *b;
Ximfix f;
Keyreq req;
Keyres res;
Ic state;
xcb_keysym_t key, *oldkmap;
uint8_t oldmin, oldmax, oldper;
ic = (xcb_im_input_context_t*)(uintptr)71;
memset(&state, 0, sizeof state);
oldkmap = kmap;
oldmin = minkc;
oldmax = maxkc;
oldper = symsper;
if(!ximbegin(t, &f, LangJP))
goto cleanup;
wireclear();
@@ -738,14 +741,23 @@ xim_adapter_placement_updates(struct ct *t)
b->preattr.spot_location.x = 5;
b->preattr.spot_location.y = 6;
wirewin(0, 11, 100, 200, 30);
CT_CHECK(t, readattrs(&state));
place(&state);
CT_CHECK(t, !readattrs(&state));
keypress(&state, 'x', 0, &res);
key = 'n';
kmap = &key;
minkc = maxkc = 8;
symsper = 1;
memset(&ev, 0, sizeof ev);
ev.detail = 8;
kpress(&state, &ev);
req = nexttrace(t, &f, Keypress, &state);
CT_CHECK(t, req.caret.valid);
CT_EQ_INT(t, 105, req.caret.x);
CT_EQ_INT(t, 206, req.caret.y);
wirewins[0].rootx = 150;
wirewins[0].rooty = 250;
kpress(&state, &ev);
req = nexttrace(t, &f, Keypress, &state);
CT_EQ_INT(t, 155, req.caret.x);
CT_EQ_INT(t, 256, req.caret.y);
b->preattr.spot_location.x = 15;
b->preattr.spot_location.y = 16;
@@ -754,11 +766,10 @@ xim_adapter_placement_updates(struct ct *t)
callback(nil, nil, ic, &hdr, nil, nil, nil);
req = nexttrace(t, &f, Keycaret, &state);
CT_CHECK(t, req.caret.valid);
CT_EQ_INT(t, 115, req.caret.x);
CT_EQ_INT(t, 216, req.caret.y);
CT_EQ_INT(t, 165, req.caret.x);
CT_EQ_INT(t, 266, req.caret.y);
CT_EQ_INT(t, 15, state.spot.x);
CT_EQ_INT(t, 16, state.spot.y);
CT_CHECK(t, !readattrs(&state));
b->preattrmask = 0;
wirewins[0].geometryok = 0;
hdr.major_opcode = XCB_XIM_SET_IC_FOCUS;
@@ -766,6 +777,10 @@ xim_adapter_placement_updates(struct ct *t)
req = nexttrace(t, &f, Keycaret, &state);
CT_CHECK(t, !req.caret.valid);
cleanup:
kmap = oldkmap;
minkc = oldmin;
maxkc = oldmax;
symsper = oldper;
preowner = nil;
ximend(&f);
}

View File

@@ -421,7 +421,7 @@ release(Ic *state)
}
static void
kpress(Ic *state, xcb_im_input_context_t *ic, xcb_key_press_event_t *ev)
kpress(Ic *state, xcb_key_press_event_t *ev)
{
Keyres res;
char buf[Maxutf];
@@ -438,10 +438,7 @@ kpress(Ic *state, xcb_im_input_context_t *ic, xcb_key_press_event_t *ev)
key = rune;
if(meaningful(key)){
wasvalid = state->caret.valid;
if(!state->engaged)
refreshplace(state);
else if(readattrs(state))
place(state);
if(state->engaged && wasvalid && !state->caret.valid)
sendrequest(state, Keycaret, 0, 0, &res);
}
@@ -450,7 +447,7 @@ kpress(Ic *state, xcb_im_input_context_t *ic, xcb_key_press_event_t *ev)
commit(state, buf, n);
updatepreedit(state, &res.preedit);
if(!res.eaten)
xcb_im_forward_event(xim, ic, ev);
xcb_im_forward_event(xim, state->xic, ev);
xcb_flush(conn);
}
@@ -485,8 +482,6 @@ setstyle(Ic *state, u32int style)
if(!stylecap(style, &cap))
style = XCB_IM_PreeditNothing | XCB_IM_StatusNothing;
if(state->prestarted && !(style & XCB_IM_PreeditCallbacks))
clearpreedit(state);
state->style = style;
state->cap = cap;
}
@@ -549,7 +544,7 @@ callback(xcb_im_t *im, xcb_im_client_t *client, xcb_im_input_context_t *ic,
case XCB_XIM_FORWARD_EVENT:
ev = arg;
if(ev != nil && (ev->response_type & ~0x80) == XCB_KEY_PRESS)
kpress(state, ic, ev);
kpress(state, ev);
break;
case XCB_XIM_SET_IC_VALUES:
case XCB_XIM_SET_IC_FOCUS: