[gtk/double-dead-keys-3: 2/2] imcontext: Tweak dead key handling




commit 8c7846733aa5e2bac866d8b8ac9eb4d8d1d6f527
Author: Matthias Clasen <mclasen redhat com>
Date:   Fri Mar 26 19:50:05 2021 -0400

    imcontext: Tweak dead key handling
    
    Reshuffle things to allow for a limited amount of
    dead key 'chaining'. We keep up to 2 dead keys in
    the preedit, so you can type
    <dead_acute> <dead_cedilla> <c>
    to produce ḉ, while still getting ```c with
    <dead_grave> <dead_grave> <dead_grave> <c>.

 gtk/gtkimcontextsimple.c | 92 +++++++++++++++++++++++++-----------------------
 1 file changed, 48 insertions(+), 44 deletions(-)
---
diff --git a/gtk/gtkimcontextsimple.c b/gtk/gtkimcontextsimple.c
index 204a375535..60ddbc3183 100644
--- a/gtk/gtkimcontextsimple.c
+++ b/gtk/gtkimcontextsimple.c
@@ -539,28 +539,62 @@ no_sequence_matches (GtkIMContextSimple *context_simple,
     }
   else
     {
-      if (n_compose == 2 && is_dead_key (priv->compose_buffer[0]))
+      int i;
+
+      for (i = 0; i < n_compose && is_dead_key (priv->compose_buffer[i]); i++)
+        ;
+
+      if (n_compose > 1 && i >= n_compose - 1)
         {
           gboolean need_space;
           GString *s;
 
           s = g_string_new ("");
 
-          /* dead keys are never *really* dead */
-          ch = dead_key_to_unicode (priv->compose_buffer[0], &need_space);
-          if (ch)
+          if (i == n_compose - 1)
             {
-              if (need_space)
-                g_string_append_c (s, ' ');
-              g_string_append_unichar (s, ch);
+              /* dead keys are never *really* dead */
+              for (int j = 0; j < i; j++)
+                {
+                  ch = dead_key_to_unicode (priv->compose_buffer[j], &need_space);
+                  if (ch)
+                    {
+                      if (need_space)
+                        g_string_append_c (s, ' ');
+                      g_string_append_unichar (s, ch);
+                    }
+                }
+
+              ch = gdk_keyval_to_unicode (priv->compose_buffer[i]);
+              if (ch != 0 && ch != ' ' && !g_unichar_iscntrl (ch))
+                g_string_append_unichar (s, ch);
+
+              gtk_im_context_simple_commit_string (context_simple, s->str);
             }
+          else
+            {
+              ch = dead_key_to_unicode (priv->compose_buffer[0], &need_space);
+              if (ch)
+                {
+                  if (need_space)
+                    g_string_append_c (s, ' ');
+                  g_string_append_unichar (s, ch);
+                }
+
+              gtk_im_context_simple_commit_string (context_simple, s->str);
+
+              for (i = 1; i < n_compose; i++)
+                priv->compose_buffer[i - 1] = priv->compose_buffer[i];
+              priv->compose_buffer[n_compose - 1] = 0;
+
+              priv->in_compose_sequence = TRUE;
 
-          ch = gdk_keyval_to_unicode (priv->compose_buffer[1]);
-          if (ch != 0 && !g_unichar_iscntrl (ch))
-            g_string_append_unichar (s, ch);
+              g_signal_emit_by_name (context, "preedit-start");
+              g_signal_emit_by_name (context, "preedit-changed");
+            }
 
-          gtk_im_context_simple_commit_string (context_simple, s->str);
           g_string_free (s, TRUE);
+
           return TRUE;
         }
 
@@ -895,39 +929,6 @@ gtk_im_context_simple_filter_keypress (GtkIMContext *context,
 
       output = g_string_new ("");
 
-      if (n_compose == 2)
-        {
-          /* Special-case deadkey-deadkey sequences.
-           * We are not doing chained deadkeys, so we
-           * want to commit the first key, and contine
-           * preediting with second.
-           */
-          if (is_dead_key (priv->compose_buffer[0]) &&
-              is_dead_key (priv->compose_buffer[1]))
-            {
-              gunichar ch;
-              gboolean need_space;
-              guint next;
-
-              next = priv->compose_buffer[1];
-
-              ch = dead_key_to_unicode (priv->compose_buffer[0], &need_space);
-              if (ch)
-                {
-                  if (need_space)
-                    g_string_append_c (output, ' ');
-                  g_string_append_unichar (output, ch);
-
-                  gtk_im_context_simple_commit_string (context_simple, output->str);
-                  g_string_set_size (output, 0);
-
-                  priv->compose_buffer[0] = next;
-                  priv->compose_buffer[1] = 0;
-                  n_compose = 1;
-                }
-            }
-        }
-
       G_LOCK (global_tables);
 
       tmp_list = global_tables;
@@ -1013,6 +1014,9 @@ gtk_im_context_simple_filter_keypress (GtkIMContext *context,
 
           if (output_char)
             gtk_im_context_simple_commit_char (context_simple, output_char);
+          else
+            g_signal_emit_by_name (context_simple, "preedit-changed");
+
           return TRUE;
         }
     }


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