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>.
This commit is contained in:
Matthias Clasen
2021-03-26 19:50:05 -04:00
parent 58b3145c90
commit 8c7846733a

View File

@ -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;
g_signal_emit_by_name (context, "preedit-start");
g_signal_emit_by_name (context, "preedit-changed");
}
ch = gdk_keyval_to_unicode (priv->compose_buffer[1]);
if (ch != 0 && !g_unichar_iscntrl (ch))
g_string_append_unichar (s, ch);
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;
}
}