diff options
author | Matthias Clasen <mclasen@redhat.com> | 2021-03-27 01:22:41 +0000 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2021-03-27 01:22:41 +0000 |
commit | c9ab7c5750b11ea6a1eba10c6ceadd92a0b1dd81 (patch) | |
tree | ac3c3e1ae1c1f3c82e1987d49e962bf73708ce75 | |
parent | f6f07ba238b4f734d9134c5e3a5e726ce8cb5fea (diff) | |
parent | 01f4e5c8cd01927855a25df86230c81e2341bfaf (diff) | |
download | gtk+-c9ab7c5750b11ea6a1eba10c6ceadd92a0b1dd81.tar.gz |
Merge branch 'double-dead-keys' into 'master'
Double dead keys
See merge request GNOME/gtk!3355
-rw-r--r-- | gtk/gtkcomposetable.c | 6 | ||||
-rw-r--r-- | gtk/gtkimcontextsimple.c | 92 | ||||
-rw-r--r-- | testsuite/gtk/composetable.c | 28 |
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 |