summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2021-03-27 01:22:41 +0000
committerMatthias Clasen <mclasen@redhat.com>2021-03-27 01:22:41 +0000
commitc9ab7c5750b11ea6a1eba10c6ceadd92a0b1dd81 (patch)
treeac3c3e1ae1c1f3c82e1987d49e962bf73708ce75
parentf6f07ba238b4f734d9134c5e3a5e726ce8cb5fea (diff)
parent01f4e5c8cd01927855a25df86230c81e2341bfaf (diff)
downloadgtk+-c9ab7c5750b11ea6a1eba10c6ceadd92a0b1dd81.tar.gz
Merge branch 'double-dead-keys' into 'master'
Double dead keys See merge request GNOME/gtk!3355
-rw-r--r--gtk/gtkcomposetable.c6
-rw-r--r--gtk/gtkimcontextsimple.c92
-rw-r--r--testsuite/gtk/composetable.c28
3 files changed, 81 insertions, 45 deletions
diff --git a/gtk/gtkcomposetable.c b/gtk/gtkcomposetable.c
index fb5ab6abe6..7aa9792e3b 100644
--- a/gtk/gtkcomposetable.c
+++ b/gtk/gtkcomposetable.c
@@ -1190,6 +1190,12 @@ gtk_check_algorithmically (const guint16 *compose_buffer,
for (i = 0; i < n_compose && IS_DEAD_KEY (compose_buffer[i]); i++)
;
+
+ /* Allow at most 2 dead keys */
+ if (i > 2)
+ return FALSE;
+
+ /* Can't combine if there's no base character */
if (i == n_compose)
return TRUE;
diff --git a/gtk/gtkimcontextsimple.c b/gtk/gtkimcontextsimple.c
index 9c1024e0c3..71044294e5 100644
--- a/gtk/gtkimcontextsimple.c
+++ b/gtk/gtkimcontextsimple.c
@@ -563,30 +563,62 @@ no_sequence_matches (GtkIMContextSimple *context_simple,
}
else
{
- keyval = gdk_key_event_get_keyval (event);
+ int i;
+
+ for (i = 0; i < n_compose && is_dead_key (priv->compose_buffer[i]); i++)
+ ;
- if (n_compose == 2 && is_dead_key (priv->compose_buffer[0]))
+ 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;
}
@@ -599,6 +631,7 @@ no_sequence_matches (GtkIMContextSimple *context_simple,
return TRUE;
}
+ keyval = gdk_key_event_get_keyval (event);
ch = gdk_keyval_to_unicode (keyval);
if (ch != 0 && !g_unichar_iscntrl (ch))
{
@@ -922,39 +955,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;
@@ -1040,6 +1040,8 @@ 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;
}
diff --git a/testsuite/gtk/composetable.c b/testsuite/gtk/composetable.c
index b41faf08f2..da28cda6d1 100644
--- a/testsuite/gtk/composetable.c
+++ b/testsuite/gtk/composetable.c
@@ -284,6 +284,34 @@ match_algorithmic (void)
ret = gtk_check_algorithmically (buffer, 3, &ch);
g_assert_true (ret);
g_assert_true (ch == 0x1f07);
+
+ buffer[0] = GDK_KEY_dead_acute;
+ buffer[1] = GDK_KEY_dead_cedilla;
+ buffer[2] = GDK_KEY_c;
+
+ ret = gtk_check_algorithmically (buffer, 2, &ch);
+ g_assert_true (ret);
+ g_assert_cmphex (ch, ==, 0);
+
+ ret = gtk_check_algorithmically (buffer, 3, &ch);
+ g_assert_true (ret);
+ g_assert_cmphex (ch, ==, 0x1e09);
+
+ buffer[0] = GDK_KEY_dead_cedilla;
+ buffer[1] = GDK_KEY_dead_acute;
+ buffer[2] = GDK_KEY_c;
+
+ ret = gtk_check_algorithmically (buffer, 3, &ch);
+ g_assert_true (ret);
+ g_assert_cmphex (ch, ==, 0x1e09);
+
+ ret = gtk_check_algorithmically (buffer, 2, &ch);
+ buffer[0] = GDK_KEY_dead_acute;
+ buffer[1] = GDK_KEY_dead_cedilla;
+ buffer[2] = GDK_KEY_dead_grave;
+
+ ret = gtk_check_algorithmically (buffer, 3, &ch);
+ g_assert_false (ret);
}
int