summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2021-02-18 18:41:37 +0000
committerMatthias Clasen <mclasen@redhat.com>2021-02-18 18:41:37 +0000
commit784b23696407211980a0e83de6587480ef31c065 (patch)
treecdc1d3436025f7edadcde4d94ff2e97dc6322157
parenta048da02d55c0dd1b88624a8cfd3f47edf16981e (diff)
parentf8206f18b1c1c311174795cea9afdc20ba76a5bb (diff)
downloadgtk+-784b23696407211980a0e83de6587480ef31c065.tar.gz
Merge branch 'unintrusive-compose-preedit-3' into 'gtk-3-24'
Unintrusive compose preedit 3 See merge request GNOME/gtk!3221
-rw-r--r--gtk/gtkimcontextsimple.c94
-rw-r--r--modules/input/imwayland.c35
2 files changed, 126 insertions, 3 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);
+ }
+ }
}
}
diff --git a/modules/input/imwayland.c b/modules/input/imwayland.c
index 87c4ae806f..a9bddd29bb 100644
--- a/modules/input/imwayland.c
+++ b/modules/input/imwayland.c
@@ -483,6 +483,39 @@ gtk_im_context_wayland_finalize (GObject *object)
G_OBJECT_CLASS (parent_class)->finalize (object);
}
+/* We want a unified experience between GtkIMContextSimple and IBus / Wayland
+ * when it comes to Compose sequences. IBus initial implementation of preedit
+ * for Compose sequences shows U+2384, which has been described as 'distracting'.
+ * This function tries to detect this case, and tweaks the text to match what
+ * GtkIMContextSimple produces.
+ */
+static char *
+tweak_preedit (const char *text)
+{
+ GString *s;
+ guint len;
+
+ s = g_string_new ("");
+
+ len = g_utf8_strlen (text, -1);
+
+ for (const char *p = text; *p; p = g_utf8_next_char (p))
+ {
+ gunichar ch = g_utf8_get_char (p);
+
+ if (ch == 0x2384)
+ {
+ if (len == 1 || p > text)
+ g_string_append (s, "·");
+ }
+ else
+ g_string_append_unichar (s, ch);
+ }
+
+ return g_string_free (s, FALSE);
+}
+
+
static void
gtk_im_context_wayland_get_preedit_string (GtkIMContext *context,
gchar **str,
@@ -512,7 +545,7 @@ gtk_im_context_wayland_get_preedit_string (GtkIMContext *context,
context_wayland->current_preedit.text ? context_wayland->current_preedit.text : "";
if (str)
- *str = g_strdup (preedit_str);
+ *str = tweak_preedit (preedit_str);
if (cursor_pos)
*cursor_pos = g_utf8_strlen (preedit_str,
context_wayland->current_preedit.cursor_begin);