gtkimcontextwayland: Shuffle full resets after IM changes
authorCarlos Garnacho <carlosg@gnome.org>
Sat, 24 Sep 2022 09:45:18 +0000 (11:45 +0200)
committerCarlos Garnacho <carlosg@gnome.org>
Sat, 24 Sep 2022 09:52:16 +0000 (11:52 +0200)
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
gtk/gtktext.c
gtk/gtktextview.c

index b5195e28d7fda58e5d5e23afbbfd153ad815b979..59c7471bf9bc001ae5d916f2aab153d4e6749146 100644 (file)
@@ -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
index 796683e44e3cf9972b1d01ff07a244d410a53b81..d7d7074d49da5b7e43527e676ce5653682c70324 100644 (file)
@@ -4241,7 +4241,6 @@ gtk_text_commit_cb (GtkIMContext *context,
     {
       gtk_text_enter_text (self, str);
       gtk_text_obscure_mouse_cursor (self);
-      gtk_im_context_reset (context);
     }
 }
 
@@ -4302,7 +4301,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;
index 2e600e01bb92c52ca3c9f0c9d1c43af3eab965c0..a2ee724ea1e7f02054b9f4fd8c703af62470b340 100644 (file)
@@ -8485,7 +8485,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
@@ -8695,9 +8694,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;
 }