[gtk/gtk-4-6: 9/11] gtkimcontextwayland: Shuffle full resets after IM changes




commit 06afb5d3545b2cfbaa480a544c901fc5b7eabda7
Author: Carlos Garnacho <carlosg gnome org>
Date:   Sat Sep 24 11:45:18 2022 +0200

    gtkimcontextwayland: Shuffle full resets after IM changes
    
    Doing reset() on the text widgets after commit and delete_surrounding
    is still too eager for some IMs (e.g. those that expect being able
    to commit text while keeping a preedit buffer shown).
    
    However, reset() is more of a "synchronize state" action on Wayland,
    and it is still desirable to do that after changes that do come from
    the IM (e.g. requesting the new surrounding text and cursor/anchor
    positions). Notably here, the text_input protocol may still come up
    with a preedit string after this state synchronization happens.
    
    Shuffle the code so that the text widgets do not reset() the IM
    context after text is deleted or committed, but the Wayland IM does
    apply its practical effects after these actions happen. This keeps
    the Wayland IM fully up-to-date wrt text widget state, while not
    altering the ::commit and ::delete-surrounding-text behavior for
    other IM context implementations.
    
    Closes: https://gitlab.gnome.org/GNOME/gtk/-/issues/5200
    Fixes: 5b78fe2721 (gtktextview: Also reset IM context after IM...)
    Fixes: 7c0a395ff9 (gtktext: Also reset IM context after IM...)
    Fixes: 52ac71b972 (gtktextview: Shuffle the places doing IM reset)
    Fixes: 9e29739e66 (gtktext: Shuffle the places doing IM reset)

 gtk/gtkimcontextwayland.c | 23 ++++++++++++++++++++---
 gtk/gtktext.c             |  2 --
 gtk/gtktextview.c         |  6 ++----
 3 files changed, 22 insertions(+), 9 deletions(-)
---
diff --git a/gtk/gtkimcontextwayland.c b/gtk/gtkimcontextwayland.c
index e4469b05aa..2e91c04e4c 100644
--- a/gtk/gtkimcontextwayland.c
+++ b/gtk/gtkimcontextwayland.c
@@ -263,9 +263,14 @@ text_input_delete_surrounding_text_apply (GtkIMContextWaylandGlobal *global)
   len = context->pending_surrounding_delete.after_length
       + context->pending_surrounding_delete.before_length;
   if (len > 0)
-    g_signal_emit_by_name (global->current, "delete-surrounding",
-                           -context->pending_surrounding_delete.before_length,
-                           len, &retval);
+    {
+      g_signal_emit_by_name (global->current, "delete-surrounding",
+                             -context->pending_surrounding_delete.before_length,
+                             len, &retval);
+      notify_im_change (GTK_IM_CONTEXT_WAYLAND (context),
+                        ZWP_TEXT_INPUT_V3_CHANGE_CAUSE_INPUT_METHOD);
+    }
+
   context->pending_surrounding_delete = defaults;
 }
 
@@ -958,6 +963,17 @@ gtk_im_context_wayland_get_surrounding (GtkIMContext  *context,
   return TRUE;
 }
 
+static void
+gtk_im_context_wayland_commit (GtkIMContext *context,
+                               const gchar  *str)
+{
+  if (GTK_IM_CONTEXT_CLASS (gtk_im_context_wayland_parent_class)->commit)
+    GTK_IM_CONTEXT_CLASS (gtk_im_context_wayland_parent_class)->commit (context, str);
+
+  notify_im_change (GTK_IM_CONTEXT_WAYLAND (context),
+                    ZWP_TEXT_INPUT_V3_CHANGE_CAUSE_INPUT_METHOD);
+}
+
 static void
 gtk_im_context_wayland_class_init (GtkIMContextWaylandClass *klass)
 {
@@ -976,6 +992,7 @@ gtk_im_context_wayland_class_init (GtkIMContextWaylandClass *klass)
   im_context_class->set_use_preedit = gtk_im_context_wayland_set_use_preedit;
   im_context_class->set_surrounding_with_selection = gtk_im_context_wayland_set_surrounding;
   im_context_class->get_surrounding_with_selection = gtk_im_context_wayland_get_surrounding;
+  im_context_class->commit = gtk_im_context_wayland_commit;
 }
 
 static void
diff --git a/gtk/gtktext.c b/gtk/gtktext.c
index d96482ec1c..6c13cd1907 100644
--- a/gtk/gtktext.c
+++ b/gtk/gtktext.c
@@ -4276,7 +4276,6 @@ gtk_text_commit_cb (GtkIMContext *context,
     {
       gtk_text_enter_text (self, str);
       gtk_text_obscure_mouse_cursor (self);
-      gtk_im_context_reset (context);
     }
 }
 
@@ -4337,7 +4336,6 @@ gtk_text_delete_surrounding_cb (GtkIMContext *context,
       gtk_editable_delete_text (GTK_EDITABLE (self),
                                 priv->current_pos + offset,
                                 priv->current_pos + offset + n_chars);
-      gtk_im_context_reset (context);
     }
 
   return TRUE;
diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c
index b587f7a96f..0108d45f52 100644
--- a/gtk/gtktextview.c
+++ b/gtk/gtktextview.c
@@ -8477,7 +8477,6 @@ gtk_text_view_commit_handler (GtkIMContext  *context,
   gtk_text_view_commit_text (text_view, str);
   gtk_text_view_reset_blink_time (text_view);
   gtk_text_view_pend_cursor_blink (text_view);
-  gtk_im_context_reset (context);
 }
 
 static void
@@ -8687,9 +8686,8 @@ gtk_text_view_delete_surrounding_handler (GtkIMContext  *context,
   gtk_text_iter_forward_chars (&start, offset);
   gtk_text_iter_forward_chars (&end, offset + n_chars);
 
-  if (gtk_text_buffer_delete_interactive (priv->buffer, &start, &end,
-                                          priv->editable))
-    gtk_im_context_reset (context);
+  gtk_text_buffer_delete_interactive (priv->buffer, &start, &end,
+                                      priv->editable);
 
   return TRUE;
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]