xim: a spot is a baseline; a popup flipped above it clears the line
An XIM spot has no height, so a popup that flips above it at the bottom of the screen ended on the baseline and covered the line being typed. The spot now stands for the row above it, one popup row tall, as GTK and IBus carets carry their line height; below the spot nothing moves.
This commit is contained in:
@@ -63,9 +63,10 @@ query; the Hanja dictionary lists one modern Hangul syllable at a time.
|
||||
Each XIM style is offered with StatusNothing and with StatusNone.
|
||||
|
||||
XIM text travels as `COMPOUND_TEXT`, which carries any UTF-8. A client that
|
||||
sends `XNSpotLocation` gets the popup at that spot whatever its preedit
|
||||
style; otherwise the popup sits under the focus window, or under the client
|
||||
window when no focus window is set.
|
||||
sends `XNSpotLocation` gets the popup under that spot whatever its preedit
|
||||
style, and above the line when there is no room below; otherwise the popup
|
||||
sits under the focus window, or under the client window when no focus
|
||||
window is set.
|
||||
|
||||
The popup is an X11 window sized by `GDK_SCALE` on HiDPI displays, XIM is
|
||||
X11-only, and GTK popup placement converts the GTK caret to X11 root
|
||||
|
||||
@@ -667,7 +667,7 @@ xim_adapter_placement(struct ct *t)
|
||||
{
|
||||
/* Spot location first, then the bottom of the focus window, then of
|
||||
* the client window; an unset focus window is the client window. */
|
||||
static const struct {
|
||||
const struct {
|
||||
u32int mask;
|
||||
int focuswin;
|
||||
int fgeo;
|
||||
@@ -677,14 +677,15 @@ xim_adapter_placement(struct ct *t)
|
||||
int valid;
|
||||
int x;
|
||||
int y;
|
||||
int h;
|
||||
} cases[] = {
|
||||
{XCB_XIM_XNSpotLocation_MASK, 10, 1, 1, 1, 1, 1, 103, 204},
|
||||
{XCB_XIM_XNSpotLocation_MASK, 10, 1, 0, 1, 1, 1, 300, 440},
|
||||
{XCB_XIM_XNSpotLocation_MASK, 0, 1, 1, 1, 1, 1, 303, 404},
|
||||
{0, 10, 1, 1, 1, 1, 1, 100, 230},
|
||||
{0, 0, 1, 1, 1, 1, 1, 300, 440},
|
||||
{0, 10, 0, 1, 1, 1, 1, 300, 440},
|
||||
{0, 10, 0, 1, 0, 1, 0, 0, 0},
|
||||
{XCB_XIM_XNSpotLocation_MASK, 10, 1, 1, 1, 1, 1, 103, 204-Fontsz, Fontsz},
|
||||
{XCB_XIM_XNSpotLocation_MASK, 10, 1, 0, 1, 1, 1, 300, 440, 0},
|
||||
{XCB_XIM_XNSpotLocation_MASK, 0, 1, 1, 1, 1, 1, 303, 404-Fontsz, Fontsz},
|
||||
{0, 10, 1, 1, 1, 1, 1, 100, 230, 0},
|
||||
{0, 0, 1, 1, 1, 1, 1, 300, 440, 0},
|
||||
{0, 10, 0, 1, 1, 1, 1, 300, 440, 0},
|
||||
{0, 10, 0, 1, 0, 1, 0, 0, 0, 0},
|
||||
};
|
||||
xcb_im_input_context_t *ic;
|
||||
Icbinding *b;
|
||||
@@ -716,7 +717,7 @@ xim_adapter_placement(struct ct *t)
|
||||
CT_EQ_INT(t, cases[i].valid, state.caret.valid);
|
||||
CT_EQ_INT(t, cases[i].x, state.caret.x);
|
||||
CT_EQ_INT(t, cases[i].y, state.caret.y);
|
||||
CT_EQ_INT(t, 0, state.caret.h);
|
||||
CT_EQ_INT(t, cases[i].h, state.caret.h);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -756,13 +757,13 @@ xim_adapter_placement_updates(struct ct *t)
|
||||
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);
|
||||
CT_EQ_INT(t, 206-Fontsz, 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);
|
||||
CT_EQ_INT(t, 256-Fontsz, req.caret.y);
|
||||
|
||||
b->preattr.spot_location.x = 15;
|
||||
b->preattr.spot_location.y = 16;
|
||||
@@ -772,7 +773,7 @@ xim_adapter_placement_updates(struct ct *t)
|
||||
req = nexttrace(t, &f, Keycaret, &state);
|
||||
CT_CHECK(t, req.caret.valid);
|
||||
CT_EQ_INT(t, 165, req.caret.x);
|
||||
CT_EQ_INT(t, 266, req.caret.y);
|
||||
CT_EQ_INT(t, 266-Fontsz, req.caret.y);
|
||||
b->preattrmask = 0;
|
||||
wirewins[0].geometryok = 0;
|
||||
hdr.major_opcode = XCB_XIM_SET_IC_FOCUS;
|
||||
|
||||
7
xim.c
7
xim.c
@@ -196,9 +196,14 @@ place(Ic *state)
|
||||
XCB_XIM_XNSpotLocation_MASK){
|
||||
attr = xcb_im_input_context_get_preedit_attr(state->xic);
|
||||
if(translate(focuswin, attr->spot_location.x,
|
||||
attr->spot_location.y, &state->caret))
|
||||
attr->spot_location.y, &state->caret)){
|
||||
/* A spot is a baseline: call the line one row above it,
|
||||
* so that a popup flipped above it clears the text. */
|
||||
state->caret.y -= Fontsz;
|
||||
state->caret.h = Fontsz;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(placebottom(state, focuswin))
|
||||
return;
|
||||
if(clientwin != focuswin)
|
||||
|
||||
Reference in New Issue
Block a user