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

View File

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