From d67fab34884cdaa6824004c5018db0c880ec4534554cc26a83531a06487cbf80 Mon Sep 17 00:00:00 2001 From: Dominique Leuenberger Date: Thu, 21 Dec 2023 10:24:39 +0000 Subject: [PATCH] Accepting request 1134406 from home:AZhou:branches:GNOME:Factory - Add mutter-fix-text-input-delete-surrounding.patch: text-input-v3 requrires byte based offset but Clutter uses char based offset for delete_surrounding_text, fix it by converting before passing arguments (glgo#GNOME/mutter#2146, glgo#GNOME/mutter!2712). OBS-URL: https://build.opensuse.org/request/show/1134406 OBS-URL: https://build.opensuse.org/package/show/GNOME:Factory/mutter?expand=0&rev=485 --- ...er-fix-text-input-delete-surrounding.patch | 207 ++++++++++++++++++ mutter.changes | 8 + mutter.spec | 3 + 3 files changed, 218 insertions(+) create mode 100644 mutter-fix-text-input-delete-surrounding.patch diff --git a/mutter-fix-text-input-delete-surrounding.patch b/mutter-fix-text-input-delete-surrounding.patch new file mode 100644 index 0000000..6ab05d4 --- /dev/null +++ b/mutter-fix-text-input-delete-surrounding.patch @@ -0,0 +1,207 @@ +From 27bdf0c577a551254551fdaaf7870c5072707c69 Mon Sep 17 00:00:00 2001 +From: Alynx Zhou +Date: Fri, 25 Nov 2022 15:48:01 +0800 +Subject: [PATCH 1/2] wayland/text-input: Use byte 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 mutter by saving committed surrounding text in +MetaWaylandTextInput and converting char based offset to byte based +offset with the UTF-8 encoded surrounding text. + +Fixes . + +Part-of: +--- + src/wayland/meta-wayland-text-input.c | 55 +++++++++++++++++++++++---- + 1 file changed, 47 insertions(+), 8 deletions(-) + +diff --git a/src/wayland/meta-wayland-text-input.c b/src/wayland/meta-wayland-text-input.c +index b1ceb1a6bb5..2e694dc1eb8 100644 +--- a/src/wayland/meta-wayland-text-input.c ++++ b/src/wayland/meta-wayland-text-input.c +@@ -58,6 +58,20 @@ struct _MetaWaylandTextInput + + GHashTable *resource_serials; + ++ /* This saves the uncommitted middle state of surrounding text from client ++ * between `set_surrounding_text` and `commit`, will be cleared after ++ * committed. ++ */ ++ struct ++ { ++ char *text; ++ uint32_t cursor; ++ uint32_t anchor; ++ } pending_surrounding; ++ ++ /* This is the actual committed surrounding text after `commit`, we need this ++ * to convert between char based offset and byte based offset. ++ */ + struct + { + char *text; +@@ -216,14 +230,32 @@ meta_wayland_text_input_focus_delete_surrounding (ClutterInputFocus *focus, + guint len) + { + MetaWaylandTextInput *text_input; ++ const char *start, *end; ++ const char *before, *after; ++ const char *cursor; + uint32_t before_length; + uint32_t after_length; + struct wl_resource *resource; + ++ /* offset and len are counted by UTF-8 chars, but text_input_v3's lengths are ++ * counted by bytes, so we convert UTF-8 char offsets to pointers here, this ++ * needs the surrounding text ++ */ + text_input = META_WAYLAND_TEXT_INPUT_FOCUS (focus)->text_input; +- before_length = ABS (MIN (offset, 0)); +- after_length = MAX (0, offset + len); +- g_warn_if_fail (ABS (offset) <= len); ++ offset = MIN (offset, 0); ++ ++ start = text_input->surrounding.text; ++ end = start + strlen (text_input->surrounding.text); ++ cursor = start + text_input->surrounding.cursor; ++ ++ before = g_utf8_offset_to_pointer (cursor, offset); ++ g_assert (before >= start); ++ ++ after = g_utf8_offset_to_pointer (cursor, offset + len); ++ g_assert (after <= end); ++ ++ before_length = cursor - before; ++ after_length = after - cursor; + + wl_resource_for_each (resource, &text_input->focus_resource_list) + { +@@ -468,10 +500,10 @@ text_input_set_surrounding_text (struct wl_client *client, + if (!client_matches_focus (text_input, client)) + return; + +- g_free (text_input->surrounding.text); +- text_input->surrounding.text = g_strdup (text); +- text_input->surrounding.cursor = cursor; +- text_input->surrounding.anchor = anchor; ++ g_free (text_input->pending_surrounding.text); ++ text_input->pending_surrounding.text = g_strdup (text); ++ text_input->pending_surrounding.cursor = cursor; ++ text_input->pending_surrounding.anchor = anchor; + text_input->pending_state |= META_WAYLAND_PENDING_STATE_SURROUNDING_TEXT; + } + +@@ -591,7 +623,7 @@ text_input_set_cursor_rectangle (struct wl_client *client, + static void + meta_wayland_text_input_reset (MetaWaylandTextInput *text_input) + { +- g_clear_pointer (&text_input->surrounding.text, g_free); ++ g_clear_pointer (&text_input->pending_surrounding.text, g_free); + text_input->content_type_hint = ZWP_TEXT_INPUT_V3_CONTENT_HINT_NONE; + text_input->content_type_purpose = ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NORMAL; + text_input->text_change_cause = ZWP_TEXT_INPUT_V3_CHANGE_CAUSE_INPUT_METHOD; +@@ -651,6 +683,12 @@ text_input_commit_state (struct wl_client *client, + + if (text_input->pending_state & META_WAYLAND_PENDING_STATE_SURROUNDING_TEXT) + { ++ /* Save the surrounding text for `delete_surrounding_text`. */ ++ g_free (text_input->surrounding.text); ++ text_input->surrounding.text = g_steal_pointer (&text_input->pending_surrounding.text); ++ text_input->surrounding.cursor = text_input->pending_surrounding.cursor; ++ text_input->surrounding.anchor = text_input->pending_surrounding.anchor; ++ /* Pass the surrounding text to Clutter to handle it with input method. */ + clutter_input_focus_set_surrounding (text_input->input_focus, + text_input->surrounding.text, + text_input->surrounding.cursor, +@@ -720,6 +758,7 @@ meta_wayland_text_input_destroy (MetaWaylandTextInput *text_input) + g_object_unref (text_input->input_focus); + g_hash_table_destroy (text_input->resource_serials); + g_clear_pointer (&text_input->preedit.string, g_free); ++ g_clear_pointer (&text_input->pending_surrounding.text, g_free); + g_clear_pointer (&text_input->surrounding.text, g_free); + g_free (text_input); + } +-- +GitLab + + +From 33088d59db742cf802977a9d8ec8b4ea3ca79ea0 Mon Sep 17 00:00:00 2001 +From: Alynx Zhou +Date: Mon, 23 Oct 2023 14:32:21 +0800 +Subject: [PATCH 2/2] wayland/text-input: Pass char based offset to + ClutterInputFocus + +Wayland's text-input-v3 uses byte based offset for cursor and anchor of +surrounding text, but Clutter needs char based offset here. This commit +converts byte based offset to char based offset before passing them to +ClutterInputFocus. + +Fixes . + +Part-of: +--- + src/wayland/meta-wayland-text-input.c | 24 +++++++++++++++++++----- + 1 file changed, 19 insertions(+), 5 deletions(-) + +diff --git a/src/wayland/meta-wayland-text-input.c b/src/wayland/meta-wayland-text-input.c +index 2e694dc1eb8..c8f50847a88 100644 +--- a/src/wayland/meta-wayland-text-input.c ++++ b/src/wayland/meta-wayland-text-input.c +@@ -122,12 +122,18 @@ static void + meta_wayland_text_input_focus_request_surrounding (ClutterInputFocus *focus) + { + MetaWaylandTextInput *text_input; ++ long cursor, anchor; + ++ /* Clutter uses char offsets but text-input-v3 uses byte offsets. */ + text_input = META_WAYLAND_TEXT_INPUT_FOCUS (focus)->text_input; ++ cursor = g_utf8_strlen (text_input->surrounding.text, ++ text_input->surrounding.cursor); ++ anchor = g_utf8_strlen (text_input->surrounding.text, ++ text_input->surrounding.anchor); + clutter_input_focus_set_surrounding (focus, +- text_input->surrounding.text, +- text_input->surrounding.cursor, +- text_input->surrounding.anchor); ++ text_input->surrounding.text, ++ cursor, ++ anchor); + } + + static uint32_t +@@ -683,16 +689,24 @@ text_input_commit_state (struct wl_client *client, + + if (text_input->pending_state & META_WAYLAND_PENDING_STATE_SURROUNDING_TEXT) + { ++ long cursor, anchor; ++ + /* Save the surrounding text for `delete_surrounding_text`. */ + g_free (text_input->surrounding.text); + text_input->surrounding.text = g_steal_pointer (&text_input->pending_surrounding.text); + text_input->surrounding.cursor = text_input->pending_surrounding.cursor; + text_input->surrounding.anchor = text_input->pending_surrounding.anchor; ++ + /* Pass the surrounding text to Clutter to handle it with input method. */ ++ /* Clutter uses char offsets but text-input-v3 uses byte offsets. */ ++ cursor = g_utf8_strlen (text_input->surrounding.text, ++ text_input->surrounding.cursor); ++ anchor = g_utf8_strlen (text_input->surrounding.text, ++ text_input->surrounding.anchor); + clutter_input_focus_set_surrounding (text_input->input_focus, + text_input->surrounding.text, +- text_input->surrounding.cursor, +- text_input->surrounding.anchor); ++ cursor, ++ anchor); + } + + if (text_input->pending_state & META_WAYLAND_PENDING_STATE_INPUT_RECT) +-- +GitLab + diff --git a/mutter.changes b/mutter.changes index 5bdebe1..2437719 100644 --- a/mutter.changes +++ b/mutter.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Thu Dec 21 08:23:54 UTC 2023 - Alynx Zhou + +- Add mutter-fix-text-input-delete-surrounding.patch: text-input-v3 + requrires byte based offset but Clutter uses char based offset + for delete_surrounding_text, fix it by converting before passing + arguments (glgo#GNOME/mutter#2146, glgo#GNOME/mutter!2712). + ------------------------------------------------------------------- Mon Dec 18 06:47:32 UTC 2023 - Alynx Zhou diff --git a/mutter.spec b/mutter.spec index 12e9e3c..4297e9c 100644 --- a/mutter.spec +++ b/mutter.spec @@ -36,6 +36,8 @@ Patch1: mutter-disable-cvt-s390x.patch Patch2: mutter-window-actor-Special-case-shaped-Java-windows.patch # PATCH-FIX-UPSTREAM mutter-fix-x11-restart.patch glgo#GNOME/gnome-shell#7050 glgo#GNOME/mutter!3329 alynx.zhou@suse.com -- Fix crash on restarting mutter under x11 Patch3: mutter-fix-x11-restart.patch +# PATCH-FIX-UPSTREAM mutter-fix-text-input-delete-surrounding.patch glgo#GNOME/mutter#2146 glgo#GNOME/mutter!2712 alynx.zhou@suse.com -- Fix delete_surrounding_text of text-input-v3 +Patch4: mutter-fix-text-input-delete-surrounding.patch ## SLE-only patches start at 1000 # PATCH-FEATURE-SLE mutter-SLE-bell.patch FATE#316042 bnc#889218 idonmez@suse.com -- make audible bell work out of the box. @@ -148,6 +150,7 @@ applications that want to make use of the mutter library. %patch -P 1 -p1 %patch -P 2 -p1 %patch -P 3 -p1 +%patch -P 4 -p1 %endif # SLE-only patches and translations. %if 0%{?sle_version}