gtk inline preedit

This commit is contained in:
2026-05-28 18:50:42 +09:00
parent b842c724e2
commit 293313652f
2 changed files with 44 additions and 7 deletions

View File

@@ -12,6 +12,8 @@ struct Im
{
GtkIMContext parent;
int fd;
char pre[256];
int prelen;
};
typedef struct ImClass ImClass;
@@ -44,8 +46,8 @@ srvconnect(Im *im)
static int
readresp(Im *im, char *buf, int bufsz)
{
unsigned char hdr[2];
int n;
unsigned char hdr[2], pl;
int n, was;
if(read(im->fd, hdr, 2) != 2)
return -1;
@@ -56,6 +58,21 @@ readresp(Im *im, char *buf, int bufsz)
return -1;
buf[n] = '\0';
}
if(read(im->fd, &pl, 1) != 1)
return -1;
if(pl >= sizeof(im->pre))
return -1;
was = im->prelen;
if(pl > 0 && read(im->fd, im->pre, pl) != pl)
return -1;
im->pre[pl] = '\0';
im->prelen = pl;
if(was == 0 && pl > 0)
g_signal_emit_by_name(im, "preedit-start");
if(was != 0 || pl != 0)
g_signal_emit_by_name(im, "preedit-changed");
if(was > 0 && pl == 0)
g_signal_emit_by_name(im, "preedit-end");
return hdr[0];
}
@@ -92,7 +109,7 @@ sendreset(Im *im)
if(im->fd < 0)
return;
buf[0] = 0;
buf[0] = 1;
buf[1] = 0;
buf[2] = Kesc & 0xff;
buf[3] = Kesc >> 8;
@@ -119,7 +136,7 @@ kpress(GtkIMContext *ctx, GdkEventKey *ev)
if(key == 0)
return FALSE;
mod = mget(ev->state);
buf[0] = 0;
buf[0] = 1;
buf[1] = mod;
buf[2] = key & 0xff;
buf[3] = key >> 8;
@@ -133,6 +150,25 @@ kpress(GtkIMContext *ctx, GdkEventKey *ev)
return r != 0;
}
static void
getpreedit(GtkIMContext *ctx, gchar **str, PangoAttrList **attrs,
gint *cursor_pos)
{
Im *im;
PangoAttribute *u;
im = (Im*)ctx;
*str = g_strdup(im->pre);
*attrs = pango_attr_list_new();
if(im->prelen > 0){
u = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE);
u->start_index = 0;
u->end_index = im->prelen;
pango_attr_list_insert(*attrs, u);
}
*cursor_pos = g_utf8_strlen(im->pre, -1);
}
static void
reset(GtkIMContext *ctx)
{
@@ -171,6 +207,7 @@ classinit(ImClass *klass)
ic = GTK_IM_CONTEXT_CLASS(klass);
oc = G_OBJECT_CLASS(klass);
ic->filter_keypress = kpress;
ic->get_preedit_string = getpreedit;
ic->reset = reset;
ic->focus_out = focusout;
oc->finalize = finalize;