summarylogtreecommitdiffstats
path: root/8c7846733aa5e2bac866d8b8ac9eb4d8d1d6f527.patch
blob: cc0ff2562d211ccc3076dc88206c59220e76652a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
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>.

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;
         }
     }