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:
		| @ -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; | ||||
|         } | ||||
|     } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Matthias Clasen
					Matthias Clasen