From b72fec0a52a921b747d3f09b8792c05e574d0998 Mon Sep 17 00:00:00 2001 From: Ben Harris Date: Mon, 31 Mar 2025 10:04:18 +0100 Subject: [PATCH] Display some IM pre-edit state when painting the terminal This is approximately how it should work: term_set_preedit_text stashes data in the terminal structure and then do_paint() renders it in place of what's in the terminal buffer. Currently this only works for a single narrow character, and it copies the existing attributes under the cursor, but this might actually be enough for the UK keyboard layout in GNOME. --- terminal/terminal.c | 14 +++++++++----- terminal/terminal.h | 3 +++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/terminal/terminal.c b/terminal/terminal.c index d945494b..d8f5f5e9 100644 --- a/terminal/terminal.c +++ b/terminal/terminal.c @@ -6199,6 +6199,9 @@ static void do_paint(Terminal *term) if (i == our_curs_y && j == our_curs_x) tattr |= cursor; + if (term->preedit_char != -1) + tchar = term->preedit_char; + } /* FULL-TERMCHAR */ newline[j].attr = tattr; @@ -8115,19 +8118,20 @@ void term_notify_window_size_pixels(Terminal *term, int x, int y) void term_set_preedit_text(Terminal *term, char *preedit_text) { BinarySource src[1]; - pos oldcurs = term->curs; if (preedit_text != NULL) { debug("Pre-edit:"); BinarySource_BARE_INIT(src, preedit_text, strlen(preedit_text)); - while (get_avail(src)) { + if (get_avail(src)) { unsigned int c = decode_utf8(src, NULL); debug(" U+%04X", c); - term_display_graphic_char(term, c); - } + term->preedit_char = c; + } else + term->preedit_char = -1; debug("\n"); - term->curs = oldcurs; } else { debug("Pre-edit finished\n"); + term->preedit_char = -1; } + seen_disp_event(term); } diff --git a/terminal/terminal.h b/terminal/terminal.h index df6ba4cc..b9159eb6 100644 --- a/terminal/terminal.h +++ b/terminal/terminal.h @@ -442,6 +442,9 @@ struct terminal_tag { */ struct term_userpass_state *userpass_state; bool userpass_utf8_override; + + /* Input method state. */ + int preedit_char; /* -1 for none */ }; static inline bool in_utf(Terminal *term)