mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-26 13:41:07 +00:00
Merge branch 'unintrusive-compose-preedit' into 'master'
Unintrusive compose preedit See merge request GNOME/gtk!3220
This commit is contained in:
commit
07295ac169
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -570,6 +570,38 @@ gtk_im_context_wayland_set_client_widget (GtkIMContext *context,
|
||||
}
|
||||
}
|
||||
|
||||
/* 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,
|
||||
char **str,
|
||||
@ -599,7 +631,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);
|
||||
|
Loading…
Reference in New Issue
Block a user