From ad83d616c4b66a5681a239f0a2e57bb7f3220e7b Mon Sep 17 00:00:00 2001 From: Alynx Zhou Date: Thu, 24 Nov 2022 18:18:49 +0800 Subject: [PATCH] gtkimcontextwayland: Convert byte based offset to char based offset in delete_surrounding_text ClutterInputFocus/GtkIMContext uses char based offset for delete_surrounding, however, text_input_v3 uses byte based offset for it. Currently only GTK with mutter can work correctly via text_input_v3 because they both forget to convert between char based offset and byte based offset. This commit fixes it in GTK by converting byte based offset to char based offset with the UTF-8 encoded surrounding text. Fixes . --- gtk/gtkimcontextwayland.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/gtk/gtkimcontextwayland.c b/gtk/gtkimcontextwayland.c index 0581772bd6..9701c73ae7 100644 --- a/gtk/gtkimcontextwayland.c +++ b/gtk/gtkimcontextwayland.c @@ -239,14 +239,24 @@ text_input_delete_surrounding_text (void *data, { GtkIMContextWaylandGlobal *global = data; GtkIMContextWayland *context; + char *cursor_pointer; + uint32_t char_before_length; + uint32_t char_after_length; if (!global->current) return; context = GTK_IM_CONTEXT_WAYLAND (global->current); - context->pending_surrounding_delete.before_length = before_length; - context->pending_surrounding_delete.after_length = after_length; + /* We already got byte lengths from text_input_v3, but GTK uses char lengths + * for delete_surrounding, So convert it here. + */ + cursor_pointer = context->surrounding.text + context->surrounding.cursor_idx; + char_before_length = g_utf8_pointer_to_offset (cursor_pointer - before_length, cursor_pointer); + char_after_length = g_utf8_pointer_to_offset (cursor_pointer, cursor_pointer + after_length); + + context->pending_surrounding_delete.before_length = char_before_length; + context->pending_surrounding_delete.after_length = char_after_length; } static void -- 2.30.2