From 716b06dccf124c6aabb2d2b9f47f6be41eb3a4ed Mon Sep 17 00:00:00 2001 From: Takao Fujiwara Date: Jun 27 2018 03:40:25 +0000 Subject: Enable preedit for compose keys - Fix SEGV in panel_binding_parse_accelerator --- diff --git a/.gitignore b/.gitignore index eee6095..8b6323a 100644 --- a/.gitignore +++ b/.gitignore @@ -55,3 +55,4 @@ ibus-1.3.6.tar.gz /ibus-1.5.16.tar.gz /ibus-1.5.17.tar.gz /ibus-1.5.18.tar.gz +/ibus-po-1.5.18-20180627.tar.gz diff --git a/ibus-HEAD.patch b/ibus-HEAD.patch index e95c344..c4cba91 100644 --- a/ibus-HEAD.patch +++ b/ibus-HEAD.patch @@ -8976,3 +8976,412 @@ index cd98c9d7..7beb6f0a 100644 -- 2.14.3 +From f9e30359d328054793e1e225dcf2fe537e6c8c48 Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Wed, 27 Jun 2018 12:11:41 +0900 +Subject: [PATCH] ibusenginesimple: Enable preedit for compose keys + +BUG=https://github.com/ibus/ibus/issues/1935 +--- + src/ibusenginesimple.c | 166 ++++++++++++++++++++++++++++++++++--------------- + 1 file changed, 115 insertions(+), 51 deletions(-) + +diff --git a/src/ibusenginesimple.c b/src/ibusenginesimple.c +index 94ce53b7..61dfb89f 100644 +--- a/src/ibusenginesimple.c ++++ b/src/ibusenginesimple.c +@@ -189,11 +189,12 @@ ibus_engine_simple_reset (IBusEngine *engine) + priv->tentative_match = 0; + priv->tentative_match_len = 0; + ibus_engine_hide_preedit_text ((IBusEngine *)simple); +- } +- if (priv->tentative_emoji || priv->in_emoji_sequence) { ++ } else if (priv->tentative_emoji || priv->in_emoji_sequence) { + priv->in_emoji_sequence = FALSE; + g_clear_pointer (&priv->tentative_emoji, g_free); + ibus_engine_hide_preedit_text ((IBusEngine *)simple); ++ } else if (!priv->in_hex_sequence && !priv->in_emoji_sequence) { ++ ibus_engine_hide_preedit_text ((IBusEngine *)simple); + } + } + +@@ -209,18 +210,78 @@ ibus_engine_simple_commit_char (IBusEngineSimple *simple, + priv->in_hex_sequence = FALSE; + priv->tentative_match = 0; + priv->tentative_match_len = 0; +- ibus_engine_simple_update_preedit_text (simple); + } + if (priv->tentative_emoji || priv->in_emoji_sequence) { + priv->in_emoji_sequence = FALSE; + g_clear_pointer (&priv->tentative_emoji, g_free); +- ibus_engine_simple_update_preedit_text (simple); + } +- + ibus_engine_commit_text ((IBusEngine *)simple, + ibus_text_new_from_unichar (ch)); + } + ++#define COMPOSE_KEYSYM_TO_UNICHAR(keysym, unichar) { \ ++ ++static gunichar ++ibus_keysym_to_unicode (guint16 keysym) { ++#define CASE(keysym_suffix, unicode) \ ++ case IBUS_KEY_dead_##keysym_suffix: return unicode ++ switch (keysym) { ++ CASE(a, 0x03041); ++ CASE(A, 0x03042); ++ CASE(i, 0x03043); ++ CASE(I, 0x03044); ++ CASE(u, 0x03045); ++ CASE(U, 0x03046); ++ CASE(e, 0x03047); ++ CASE(E, 0x03048); ++ CASE(o, 0x03049); ++ CASE(O, 0x0304a); ++ CASE(abovecomma, 0x0313); ++ CASE(abovedot, 0x0307); ++ CASE(abovereversedcomma, 0x0314); ++ CASE(abovering, 0x030a); ++ CASE(acute, 0x0301); ++ CASE(belowbreve, 0x032e); ++ CASE(belowcircumflex, 0x032d); ++ CASE(belowcomma, 0x0326); ++ CASE(belowdiaeresis, 0x0324); ++ CASE(belowdot, 0x0323); ++ CASE(belowmacron, 0x0331); ++ CASE(belowring, 0x030a); ++ CASE(belowtilde, 0x0330); ++ CASE(breve, 0x0306); ++ CASE(capital_schwa, 0x018f); ++ CASE(caron, 0x030c); ++ CASE(cedilla, 0x0327); ++ CASE(circumflex, 0x0302); ++ CASE(currency, 0x00a4); ++ // IBUS_KEY_dead_dasia == IBUS_KEY_dead_abovereversedcomma ++ CASE(diaeresis, 0x0308); ++ CASE(doubleacute, 0x030b); ++ CASE(doublegrave, 0x030f); ++ CASE(grave, 0x0300); ++ CASE(greek, 0x03b1); ++ CASE(hook, 0x0309); ++ CASE(horn, 0x031b); ++ CASE(invertedbreve, 0x032f); ++ CASE(iota, 0x0345); ++ CASE(macron, 0x0304); ++ CASE(ogonek, 0x0328); ++ // IBUS_KEY_dead_perispomeni == IBUS_KEY_dead_tilde ++ // IBUS_KEY_dead_psili == IBUS_KEY_dead_abovecomma ++ CASE(semivoiced_sound, 0x309a); ++ CASE(small_schwa, 0x1d4a); ++ CASE(stroke, 0x29f8); ++ CASE(tilde, 0x0303); ++ CASE(voiced_sound, 0x3099); ++ case IBUS_KEY_Multi_key: ++ return 0x2384; ++ default:; ++ } ++ return 0x0; ++#undef CASE ++} ++ + static void + ibus_engine_simple_commit_str (IBusEngineSimple *simple, + const gchar *str) +@@ -278,8 +339,7 @@ ibus_engine_simple_update_preedit_text (IBusEngineSimple *simple) + g_assert (len <= IBUS_MAX_COMPOSE_LEN + 1); + else + g_assert (len <= EMOJI_SOURCE_LEN + 1); +- } +- else if (priv->tentative_match) { ++ } else if (priv->tentative_match) { + outbuf[len++] = priv->tentative_match; + } else if (priv->tentative_emoji && *priv->tentative_emoji) { + IBusText *text = ibus_text_new_from_string (priv->tentative_emoji); +@@ -288,6 +348,24 @@ ibus_engine_simple_update_preedit_text (IBusEngineSimple *simple) + IBUS_ATTR_TYPE_UNDERLINE, IBUS_ATTR_UNDERLINE_SINGLE, 0, len); + ibus_engine_update_preedit_text ((IBusEngine *)simple, text, len, TRUE); + return; ++ } else { ++ int hexchars = 0; ++ while (priv->compose_buffer[hexchars] != 0) { ++ guint16 keysym= priv->compose_buffer[hexchars]; ++ gunichar unichar = ibus_keysym_to_unicode (keysym); ++ if (unichar > 0) ++ outbuf[len] = unichar; ++ else ++ outbuf[len] = ibus_keyval_to_unicode (keysym); ++ if (!outbuf[len]) { ++ g_warning ( ++ "Not found alternative character of compose key 0x%X", ++ priv->compose_buffer[hexchars]); ++ } ++ ++len; ++ ++hexchars; ++ } ++ g_assert (len <= IBUS_MAX_COMPOSE_LEN + 1); + } + + outbuf[len] = L'\0'; +@@ -569,8 +647,9 @@ check_table (IBusEngineSimple *simple, + } + + ibus_engine_simple_commit_char (simple, value); +- // g_debug ("U+%04X\n", value); + priv->compose_buffer[0] = 0; ++ ibus_engine_simple_update_preedit_text (simple); ++ // g_debug ("U+%04X\n", value); + } + return TRUE; + } +@@ -768,44 +847,10 @@ ibus_check_algorithmically (const guint16 *compose_buffer, + combination_buffer[n_compose] = 0; + i--; + while (i >= 0) { +- switch (compose_buffer[i]) { +-#define CASE(keysym, unicode) \ +- case IBUS_KEY_dead_##keysym: \ +- combination_buffer[i+1] = unicode; \ +- break +- CASE (grave, 0x0300); +- CASE (acute, 0x0301); +- CASE (circumflex, 0x0302); +- CASE (tilde, 0x0303); /* Also used with perispomeni, 0x342. */ +- CASE (macron, 0x0304); +- CASE (breve, 0x0306); +- CASE (abovedot, 0x0307); +- CASE (diaeresis, 0x0308); +- CASE (hook, 0x0309); +- CASE (abovering, 0x030A); +- CASE (doubleacute, 0x030B); +- CASE (caron, 0x030C); +- CASE (abovecomma, 0x0313); /* Equivalent to psili */ +- CASE (abovereversedcomma, 0x0314); /* Equivalent to dasia */ +- CASE (horn, 0x031B); /* Legacy use for psili, 0x313 (or 0x343). */ +- CASE (belowdot, 0x0323); +- CASE (cedilla, 0x0327); +- CASE (ogonek, 0x0328); /* Legacy use for dasia, 0x314.*/ +- CASE (iota, 0x0345); +- CASE (voiced_sound, 0x3099); /* Per Markus Kuhn keysyms.txt file. */ +- CASE (semivoiced_sound, 0x309A); /* Per Markus Kuhn keysyms.txt file. */ +- +- /* The following cases are to be removed once xkeyboard-config, +- * xorg are fully updated. +- */ +- /* Workaround for typo in 1.4.x xserver-xorg */ +- case 0xfe66: combination_buffer[i+1] = 0x314; break; +- /* CASE (dasia, 0x314); */ +- /* CASE (perispomeni, 0x342); */ +- /* CASE (psili, 0x343); */ +-#undef CASE +- default: +- combination_buffer[i+1] = ibus_keyval_to_unicode (compose_buffer[i]); ++ combination_buffer[i+1] = ibus_keysym_to_unicode (compose_buffer[i]); ++ if (!combination_buffer[i+1]) { ++ combination_buffer[i+1] = ++ ibus_keyval_to_unicode (compose_buffer[i]); + } + i--; + } +@@ -853,6 +898,7 @@ no_sequence_matches (IBusEngineSimple *simple, + + ibus_engine_simple_commit_char (simple, priv->tentative_match); + priv->compose_buffer[0] = 0; ++ ibus_engine_simple_update_preedit_text (simple); + + for (i=0; i < n_compose - len - 1; i++) { + ibus_engine_simple_process_key_event ( +@@ -872,20 +918,21 @@ no_sequence_matches (IBusEngineSimple *simple, + if (n_compose > 1) { + /* Invalid sequence */ + // FIXME beep_window (event->window); ++ ibus_engine_simple_update_preedit_text (simple); + return TRUE; + } + ++ ibus_engine_simple_update_preedit_text (simple); + ch = ibus_keyval_to_unicode (keyval); + /* IBUS_CHANGE: RH#769133 + * Since we use ibus xkb engines as the disable state, + * do not commit the characters locally without in_hex_sequence. */ + if (ch != 0 && !g_unichar_iscntrl (ch) && + priv->in_hex_sequence) { +- ibus_engine_simple_commit_char (simple, ch); + return TRUE; +- } +- else ++ } else { + return FALSE; ++ } + } + return FALSE; + } +@@ -1027,6 +1074,7 @@ ibus_engine_simple_process_key_event (IBusEngine *engine, + if (priv->tentative_match && + g_unichar_validate (priv->tentative_match)) { + ibus_engine_simple_commit_char (simple, priv->tentative_match); ++ ibus_engine_simple_update_preedit_text (simple); + } else if (n_compose == 0) { + priv->modifiers_dropped = TRUE; + } else { +@@ -1176,12 +1224,21 @@ ibus_engine_simple_process_key_event (IBusEngine *engine, + + return TRUE; + } ++ if (!priv->in_hex_sequence && !priv->in_emoji_sequence && is_backspace) { ++ if (n_compose > 0) { ++ n_compose--; ++ priv->compose_buffer[n_compose] = 0; ++ ibus_engine_simple_update_preedit_text (simple); ++ return TRUE; ++ } ++ } + + /* Check for hex sequence restart */ + if (priv->in_hex_sequence && have_hex_mods && is_hex_start) { + if (priv->tentative_match && + g_unichar_validate (priv->tentative_match)) { + ibus_engine_simple_commit_char (simple, priv->tentative_match); ++ ibus_engine_simple_update_preedit_text (simple); + } + else { + /* invalid hex sequence */ +@@ -1283,6 +1340,12 @@ ibus_engine_simple_process_key_event (IBusEngine *engine, + return TRUE; + } + } else { ++ if (is_escape) { ++ if (n_compose > 0) { ++ ibus_engine_simple_reset (engine); ++ return TRUE; ++ } ++ } + SET_COMPOSE_BUFFER_ELEMENT_NEXT (priv->compose_buffer, + n_compose, + keyval); +@@ -1302,6 +1365,7 @@ ibus_engine_simple_process_key_event (IBusEngine *engine, + ibus_engine_simple_commit_char (simple, + priv->tentative_match); + priv->compose_buffer[0] = 0; ++ ibus_engine_simple_update_preedit_text (simple); + } else { + // FIXME + /* invalid hex sequence */ +@@ -1417,9 +1481,8 @@ ibus_engine_simple_process_key_event (IBusEngine *engine, + if (compose_finish) { + ibus_engine_simple_commit_char (simple, output_char); + priv->compose_buffer[0] = 0; +- } else { +- ibus_engine_simple_update_preedit_text (simple); + } ++ ibus_engine_simple_update_preedit_text (simple); + return TRUE; + } + +@@ -1430,6 +1493,7 @@ ibus_engine_simple_process_key_event (IBusEngine *engine, + ibus_engine_simple_commit_char (simple, output_char); + priv->compose_buffer[0] = 0; + } ++ ibus_engine_simple_update_preedit_text (simple); + return TRUE; + } + } +-- +2.14.3 + +From 9b26a4b46fa2635033d315e8babb8c4ca9869898 Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Wed, 27 Jun 2018 12:18:26 +0900 +Subject: [PATCH] panelbinding: Fix SEGV in panel_binding_parse_accelerator + +panel_binding_parse_accelerator() could return NULL of the unowned +IBus.ProcessKeyEventData with gcc optimization. +Since Vala does not provice a static local variable, the variable is +moved to the class member to fix this SEGV. +Also a NULL preedit is fixed in the first emoji candidate from the +emoji category window. +--- + ui/gtk3/panelbinding.vala | 28 ++++++++++++++++------------ + 1 file changed, 16 insertions(+), 12 deletions(-) + +diff --git a/ui/gtk3/panelbinding.vala b/ui/gtk3/panelbinding.vala +index 52b78c17..95115b13 100644 +--- a/ui/gtk3/panelbinding.vala ++++ b/ui/gtk3/panelbinding.vala +@@ -227,6 +227,8 @@ class PanelBinding : IBus.PanelService { + private bool m_enable_extension; + private string m_extension_name = ""; + private Preedit m_preedit; ++ private IBus.ProcessKeyEventData m_key_event_data = ++ IBus.ProcessKeyEventData(); + + public PanelBinding(IBus.Bus bus, + Gtk.Application application) { +@@ -311,24 +313,24 @@ class PanelBinding : IBus.PanelService { + } + + +- private unowned +- IBus.ProcessKeyEventData? parse_accelerator(string accelerator) { +- IBus.ProcessKeyEventData key = {}; ++ // Returning unowned IBus.KeyEventData causes NULL with gcc optimization ++ // and use m_key_event_data. ++ private void parse_accelerator(string accelerator) { ++ m_key_event_data = {}; + uint keysym = 0; + IBus.ModifierType modifiers = 0; + IBus.accelerator_parse(accelerator, + out keysym, out modifiers); + if (keysym == 0U && modifiers == 0) { + warning("Failed to parse shortcut key '%s'".printf(accelerator)); +- return null; ++ return; + } + if ((modifiers & IBus.ModifierType.SUPER_MASK) != 0) { + modifiers ^= IBus.ModifierType.SUPER_MASK; + modifiers |= IBus.ModifierType.MOD4_MASK; + } +- key.keyval = keysym; +- key.state = modifiers; +- return key; ++ m_key_event_data.keyval = keysym; ++ m_key_event_data.state = modifiers; + } + + +@@ -337,8 +339,8 @@ class PanelBinding : IBus.PanelService { + IBus.ProcessKeyEventData key; + string[] accelerators = m_settings_emoji.get_strv("hotkey"); + foreach (var accelerator in accelerators) { +- key = parse_accelerator(accelerator); +- emoji_keys += key; ++ parse_accelerator(accelerator); ++ emoji_keys += m_key_event_data; + } + + /* Since {} is not allocated, parse_accelerator() should be unowned. */ +@@ -348,8 +350,8 @@ class PanelBinding : IBus.PanelService { + IBus.ProcessKeyEventData[] unicode_keys = {}; + accelerators = m_settings_emoji.get_strv("unicode-hotkey"); + foreach (var accelerator in accelerators) { +- key = parse_accelerator(accelerator); +- unicode_keys += key; ++ parse_accelerator(accelerator); ++ unicode_keys += m_key_event_data; + } + key = {}; + unicode_keys += key; +@@ -544,8 +546,10 @@ class PanelBinding : IBus.PanelService { + private bool key_press_enter() { + if (m_extension_name != "unicode" && is_emoji_lookup_table()) { + // Check if variats exist +- if (m_emojier.key_press_enter()) ++ if (m_emojier.key_press_enter()) { ++ convert_preedit_text(); + return true; ++ } + } + IBus.Text text = m_preedit.get_commit_text(); + commit_text_update_favorites(text); +-- +2.14.3 + diff --git a/ibus.spec b/ibus.spec index 8ccc98e..9fa348b 100644 --- a/ibus.spec +++ b/ibus.spec @@ -39,7 +39,7 @@ Name: ibus Version: 1.5.18 -Release: 7%{?dist} +Release: 8%{?dist} Summary: Intelligent Input Bus for Linux OS License: LGPLv2+ Group: System Environment/Libraries @@ -47,6 +47,7 @@ URL: https://github.com/ibus/%name/wiki Source0: https://github.com/ibus/%name/releases/download/%{version}/%{name}-%{version}.tar.gz Source1: %{name}-xinput Source2: %{name}.conf.5 +Source3: %{name}-po-1.5.18-20180627.tar.gz # Will remove the annotation tarball once the rpm is available on Fedora # Upstreamed patches. # Patch0: %%{name}-HEAD.patch @@ -251,6 +252,7 @@ The ibus-devel-docs package contains developer documentation for IBus %prep %autosetup -S git +zcat %SOURCE3 | tar xfv - # cp client/gtk2/ibusimcontext.c client/gtk3/ibusimcontext.c || # prep test @@ -433,6 +435,10 @@ dconf update || : %{_datadir}/gtk-doc/html/* %changelog +* Wed Jun 27 2018 Takao Fujiwara - 1.5.18-8 +- Enable preedit for compose keys +- Fix SEGV in panel_binding_parse_accelerator + * Wed Jun 20 2018 Takao Fujiwara - 1.5.18-7 - Moved input focus on Emojier to engines' preedit - Removed ibus-xx-emoji-harfbuzz.patch not to change session emoji font diff --git a/sources b/sources index 1e7bcef..7ad275d 100644 --- a/sources +++ b/sources @@ -1 +1,2 @@ SHA512 (ibus-1.5.18.tar.gz) = 34519c3464eaf2cac3320e1568fc76f4edb281afa70f335c015b828ff4e86b3224d77b95cdc0b2e76e42459c54b1044264ff226963fe739dd553ac7326d2f2d3 +SHA512 (ibus-po-1.5.18-20180627.tar.gz) = bd55883fc7b0810e59cc0de0a1a0e39e9a9ee3f8d20001420b9d6f2aefe5fe00a821dae8af3d1e3c3b8b056f8cb0dcc625f6dc14205b72f12a874b956d4e713b