[gtk/unintrusive-compose-preedit-3: 1/2] imcontext: Make Compose preedit less intrusive




commit 523d5121d303fb91e004ea37ce55867008cb2dd7
Author: Matthias Clasen <mclasen redhat com>
Date:   Wed Feb 17 19:59:28 2021 -0500

    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.

 gtk/gtkimcontextsimple.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 92 insertions(+), 2 deletions(-)
---
diff --git a/gtk/gtkimcontextsimple.c b/gtk/gtkimcontextsimple.c
index 627ed71c23..39a659edda 100644
--- a/gtk/gtkimcontextsimple.c
+++ b/gtk/gtkimcontextsimple.c
@@ -907,9 +907,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);
+                }
+            }
         }
     }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]