diff --git a/ime.c b/ime.c index eda975c5..9bcf0a9f 100644 --- a/ime.c +++ b/ime.c @@ -9,6 +9,7 @@ #include "log.h" #include "terminal.h" #include "wayland.h" +#include "xmalloc.h" static void enter(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, @@ -51,6 +52,7 @@ enter(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, } zwp_text_input_v3_commit(seat->wl_text_input); + seat->ime.serial++; } static void @@ -61,6 +63,7 @@ leave(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, LOG_DBG("leave: seat=%s", seat->name); zwp_text_input_v3_disable(seat->wl_text_input); zwp_text_input_v3_commit(seat->wl_text_input); + seat->ime.serial++; } static void @@ -68,15 +71,23 @@ preedit_string(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, const char *text, int32_t cursor_begin, int32_t cursor_end) { LOG_DBG("preedit-string: text=%s, begin=%d, end=%d", text, cursor_begin, cursor_end); + struct seat *seat = data; + + free(seat->ime.preedit.text); + seat->ime.preedit.text = text != NULL ? xstrdup(text) : NULL; + seat->ime.preedit.cursor_begin = cursor_begin; + seat->ime.preedit.cursor_end = cursor_end; } static void commit_string(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, const char *text) { - struct seat *seat = data; LOG_DBG("commit: text=%s", text); - term_to_slave(seat->kbd_focus, text, strlen(text)); + struct seat *seat = data; + free(seat->ime.commit.text); + seat->ime.commit.text = text != NULL ? xstrdup(text) : NULL; + //term_to_slave(seat->kbd_focus, text, strlen(text)); } static void @@ -84,13 +95,40 @@ delete_surrounding_text(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, uint32_t before_length, uint32_t after_length) { LOG_DBG("delete-surrounding: before=%d, after=%d", before_length, after_length); + struct seat *seat = data; + seat->ime.surrounding.before_length = before_length; + seat->ime.surrounding.after_length = after_length; } static void done(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, uint32_t serial) { + /* + * The application must proceed by evaluating the changes in the + * following order: + * + * 1. Replace existing preedit string with the cursor. 2. Delete + * requested surrounding text. 3. Insert commit string with the + * cursor at its end. 4. Calculate surrounding text to send. 5. + * Insert new preedit text in cursor position. 6. Place cursor + * inside preedit text. + */ + LOG_DBG("done: serial=%u", serial); + struct seat *seat = data; + + if (seat->ime.serial != serial) + LOG_WARN("IME serial mismatch: expected=0x%08x, got 0x%08x", + seat->ime.serial, serial); + + assert(seat->kbd_focus); + + if (seat->ime.commit.text != NULL) + term_to_slave(seat->kbd_focus, seat->ime.commit.text, strlen(seat->ime.commit.text)); + + free(seat->ime.commit.text); + seat->ime.commit.text = NULL; } const struct zwp_text_input_v3_listener text_input_listener = { diff --git a/input.c b/input.c index 31c1d816..4abbb89e 100644 --- a/input.c +++ b/input.c @@ -21,7 +21,7 @@ #include #define LOG_MODULE "input" -#define LOG_ENABLE_DBG 0 +#define LOG_ENABLE_DBG 1 #include "log.h" #include "config.h" #include "commands.h" @@ -752,6 +752,8 @@ keymap_lookup(struct seat *seat, struct terminal *term, const enum keypad_keys keypad_keys_mode = term->num_lock_modifier ? KEYPAD_NUMERICAL : term->keypad_keys_mode; + log_dbg("keypad mode: %d, num-lock=%d", keypad_keys_mode, seat->kbd.num); + for (size_t j = 0; j < count; j++) { if (info[j].modifiers != MOD_ANY && info[j].modifiers != mods) continue; diff --git a/vt.c b/vt.c index ed26da73..1522dacf 100644 --- a/vt.c +++ b/vt.c @@ -408,7 +408,7 @@ action_esc_dispatch(struct terminal *term, uint8_t final) case '=': term->keypad_keys_mode = KEYPAD_APPLICATION; break; - +รถ case '>': term->keypad_keys_mode = KEYPAD_NUMERICAL; break; diff --git a/wayland.c b/wayland.c index 2f7b3b95..ecaecb1c 100644 --- a/wayland.c +++ b/wayland.c @@ -191,6 +191,8 @@ seat_destroy(struct seat *seat) free(seat->clipboard.text); free(seat->primary.text); + free(seat->ime.preedit.text); + free(seat->ime.commit.text); free(seat->name); } diff --git a/wayland.h b/wayland.h index e006b395..b29bb8ab 100644 --- a/wayland.h +++ b/wayland.h @@ -223,8 +223,24 @@ struct seat { /* Input Method Editor */ struct zwp_text_input_v3 *wl_text_input; - //struct { - //} ime; + struct { + struct { + char *text; + int32_t cursor_begin; + int32_t cursor_end; + } preedit; + + struct { + char *text; + } commit; + + struct { + uint32_t before_length; + uint32_t after_length; + } surrounding; + + uint32_t serial; + } ime; }; enum csd_surface {