summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2021-02-17 19:59:28 -0500
committerMatthias Clasen <mclasen@redhat.com>2021-02-18 11:44:09 -0500
commit4327a866f4f05fc7953464f212def71da8fbabde (patch)
tree3cc9f8a9f7ded5537373b33b4b7e81c8f9d2af7d
parent32c7ca50eafde6e762c2496b711168379e9f33fb (diff)
downloadgtk+-4327a866f4f05fc7953464f212def71da8fbabde.tar.gz
imcontext: Make Compose preedit less intrusive
Tweak the preedit display for Compose sequences to be not so distracting. We only show the Compose key when it occurs in the middle of the sequence or is the only key so far, and use · instead of ⎄ for it. Also, make sure to display dead keys more adequately.
-rw-r--r--gtk/gtkimcontextsimple.c94
1 files changed, 92 insertions, 2 deletions
diff --git a/gtk/gtkimcontextsimple.c b/gtk/gtkimcontextsimple.c
index b8fec2f384..86e133fc86 100644
--- a/gtk/gtkimcontextsimple.c
+++ b/gtk/gtkimcontextsimple.c
@@ -930,9 +930,99 @@ gtk_im_context_simple_get_preedit_string (GtkIMContext *context,
for (i = 0; priv->compose_buffer[i]; i++)
{
if (priv->compose_buffer[i] == GDK_KEY_Multi_key)
- g_string_append_unichar (s, 0x2384); /* U+2384 COMPOSITION SYMBOL */
+ {
+ /* We only show the Compose key visibly when it is the
+ * only glyph in the preedit, or when it occurs in the
+ * middle of the sequence. Sadly, the official character,
+ * U+2384, COMPOSITION SYMBOL, is bit too distracting, so
+ * we use U+00B7, MIDDLE DOT.
+ */
+ if (priv->compose_buffer[1] == 0 || i > 0)
+ g_string_append (s, "·");
+ }
else
- g_string_append_unichar (s, gdk_keyval_to_unicode (priv->compose_buffer[i]));
+ {
+ gunichar ch;
+ gboolean need_space;
+
+ if (GDK_KEY_dead_grave <= priv->compose_buffer[i] && priv->compose_buffer[i] <= GDK_KEY_dead_greek)
+ {
+ /* Sadly, not all the dead keysyms have spacing mark equivalents
+ * in Unicode. For those that don't, we use space + the non-spacing
+ * mark as an approximation
+ */
+ switch (priv->compose_buffer[i])
+ {
+#define CASE(keysym, unicode, sp) \
+ case GDK_KEY_dead_##keysym: ch = unicode; need_space = sp; break
+
+ CASE (grave, 0x60, 0);
+ CASE (acute, 0xb4, 0);
+ CASE (circumflex, 0x5e, 0);
+ CASE (tilde, 0x7e, 0);
+ CASE (macron, 0xaf, 0);
+ CASE (breve, 0x2d8, 0);
+ CASE (abovedot, 0x307, 1);
+ CASE (diaeresis, 0xa8, 0);
+ CASE (abovering, 0x2da, 0);
+ CASE (hook, 0x2c0, 0);
+ CASE (doubleacute, 0x2dd, 0);
+ CASE (caron, 0x2c7, 0);
+ CASE (cedilla, 0xb8, 0);
+ CASE (ogonek, 0x2db, 0);
+ CASE (iota, 0x37a, 0);
+ CASE (voiced_sound, 0x3099, 1);
+ CASE (semivoiced_sound, 0x309a, 1);
+ CASE (belowdot, 0x323, 1);
+ CASE (horn, 0x31b, 1);
+ CASE (stroke, 0x335, 1);
+ CASE (abovecomma, 0x2bc, 0);
+ CASE (abovereversedcomma, 0x2bd, 1);
+ CASE (doublegrave, 0x30f, 1);
+ CASE (belowring, 0x2f3, 0);
+ CASE (belowmacron, 0x2cd, 0);
+ CASE (belowcircumflex, 0x32d, 1);
+ CASE (belowtilde, 0x330, 1);
+ CASE (belowbreve, 0x32e, 1);
+ CASE (belowdiaeresis, 0x324, 1);
+ CASE (invertedbreve, 0x32f, 1);
+ CASE (belowcomma, 0x326, 1);
+ CASE (lowline, 0x5f, 0);
+ CASE (aboveverticalline, 0x2c8, 0);
+ CASE (belowverticalline, 0x2cc, 0);
+ CASE (longsolidusoverlay, 0x338, 1);
+ CASE (a, 0x363, 1);
+ CASE (A, 0x363, 1);
+ CASE (e, 0x364, 1);
+ CASE (E, 0x364, 1);
+ CASE (i, 0x365, 1);
+ CASE (I, 0x365, 1);
+ CASE (o, 0x366, 1);
+ CASE (O, 0x366, 1);
+ CASE (u, 0x367, 1);
+ CASE (U, 0x367, 1);
+ CASE (small_schwa, 0x1dea, 1);
+ CASE (capital_schwa, 0x1dea, 1);
+#undef CASE
+ default:
+ need_space = FALSE;
+ ch = gdk_keyval_to_unicode (priv->compose_buffer[i]);
+ break;
+ }
+ if (ch)
+ {
+ if (need_space)
+ g_string_append_c (s, ' ');
+ g_string_append_unichar (s, ch);
+ }
+ }
+ else
+ {
+ ch = gdk_keyval_to_unicode (priv->compose_buffer[i]);
+ if (ch)
+ g_string_append_unichar (s, ch);
+ }
+ }
}
}