Do not use combined characters on preedit for compose keys

Fixed an infinite loop of extension preedit with xterm
This commit is contained in:
Takao Fujiwara 2018-06-29 16:50:24 +09:00
parent c082e5d25c
commit 866e11711f
2 changed files with 268 additions and 4 deletions

View File

@ -9288,21 +9288,281 @@ index 94ce53b7..61dfb89f 100644
-- --
2.14.3 2.14.3
From 9b26a4b46fa2635033d315e8babb8c4ca9869898 Mon Sep 17 00:00:00 2001 From 3a68ded197b3ad2e45ac08fe52c0514aff987367 Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com> From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Wed, 27 Jun 2018 12:18:26 +0900 Date: Fri, 29 Jun 2018 16:02:32 +0900
Subject: [PATCH] ibusenginesimple: Do not show combined character on
compose preedit
Some applications could combine their committed string with compose
character on preedit. E.g. dead_grave after 'e' on firefox
BUG=https://github.com/ibus/ibus/issues/1935
---
src/ibusenginesimple.c | 119 ++++++++++++++++++++++++++-----------------------
1 file changed, 63 insertions(+), 56 deletions(-)
diff --git a/src/ibusenginesimple.c b/src/ibusenginesimple.c
index 61dfb89f..68d6fb1e 100644
--- a/src/ibusenginesimple.c
+++ b/src/ibusenginesimple.c
@@ -219,67 +219,73 @@ ibus_engine_simple_commit_char (IBusEngineSimple *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) \
+ibus_keysym_to_unicode (guint16 keysym,
+ gboolean combining) {
+#define CASE(keysym_suffix, unicode) \
case IBUS_KEY_dead_##keysym_suffix: return unicode
+#define CASE_COMBINE(keysym_suffix, combined_unicode, isolated_unicode) \
+ case IBUS_KEY_dead_##keysym_suffix: \
+ if (combining) \
+ return combined_unicode; \
+ else \
+ return isolated_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);
+ 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_COMBINE (abovedot, 0x0307, 0x02D9);
+ CASE (abovereversedcomma, 0x0314);
+ CASE_COMBINE (abovering, 0x030A, 0x02DA);
+ CASE_COMBINE (acute, 0x0301, 0x00B4);
+ CASE (belowbreve, 0x032E);
+ CASE_COMBINE (belowcircumflex, 0x032D, 0xA788);
+ CASE_COMBINE (belowcomma, 0x0326, 0x002C);
+ CASE (belowdiaeresis, 0x0324);
+ CASE_COMBINE (belowdot, 0x0323, 0x002E);
+ CASE_COMBINE (belowmacron, 0x0331, 0x02CD);
+ CASE_COMBINE (belowring, 0x030A, 0x02F3);
+ CASE_COMBINE (belowtilde, 0x0330, 0x02F7);
+ CASE_COMBINE (breve, 0x0306, 0x02D8);
+ CASE_COMBINE (capital_schwa, 0x018F, 0x04D8);
+ CASE_COMBINE (caron, 0x030C, 0x02C7);
+ CASE_COMBINE (cedilla, 0x0327, 0x00B8);
+ CASE_COMBINE (circumflex, 0x0302, 0x005E);
+ 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);
+ CASE_COMBINE (diaeresis, 0x0308, 0x00A8);
+ CASE_COMBINE (doubleacute, 0x030B, 0x02DD);
+ CASE_COMBINE (doublegrave, 0x030F, 0x02F5);
+ CASE_COMBINE (grave, 0x0300, 0x0060);
+ CASE (greek, 0x03BC);
+ CASE (hook, 0x0309);
+ CASE (horn, 0x031B);
+ CASE (invertedbreve, 0x032F);
+ CASE_COMBINE (iota, 0x0345, 0x037A);
+ CASE_COMBINE (macron, 0x0304, 0x00AF);
+ CASE_COMBINE (ogonek, 0x0328, 0x02DB);
// 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_COMBINE (semivoiced_sound, 0x309A, 0x309C);
+ CASE_COMBINE (small_schwa, 0x1D4A, 0x04D9);
+ CASE (stroke, 0x002F);
+ CASE_COMBINE (tilde, 0x0303, 0x007E);
+ CASE_COMBINE (voiced_sound, 0x3099, 0x309B);
case IBUS_KEY_Multi_key:
return 0x2384;
default:;
}
return 0x0;
#undef CASE
+#undef CASE_COMBINE
}
static void
@@ -352,7 +358,7 @@ ibus_engine_simple_update_preedit_text (IBusEngineSimple *simple)
int hexchars = 0;
while (priv->compose_buffer[hexchars] != 0) {
guint16 keysym= priv->compose_buffer[hexchars];
- gunichar unichar = ibus_keysym_to_unicode (keysym);
+ gunichar unichar = ibus_keysym_to_unicode (keysym, FALSE);
if (unichar > 0)
outbuf[len] = unichar;
else
@@ -847,13 +853,14 @@ ibus_check_algorithmically (const guint16 *compose_buffer,
combination_buffer[n_compose] = 0;
i--;
while (i >= 0) {
- 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]);
+ combination_buffer[i+1] = ibus_keysym_to_unicode (compose_buffer[i],
+ TRUE);
+ if (!combination_buffer[i+1]) {
+ combination_buffer[i+1] =
+ ibus_keyval_to_unicode (compose_buffer[i]);
+ }
+ i--;
}
- i--;
- }
/* If the buffer normalizes to a single character,
* then modify the order of combination_buffer accordingly, if necessary,
--
2.14.3
From caffeaeee5be121713104fba331b9cf30726aa91 Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Fri, 29 Jun 2018 16:06:52 +0900
Subject: [PATCH] panelbinding: Fix SEGV in panel_binding_parse_accelerator Subject: [PATCH] panelbinding: Fix SEGV in panel_binding_parse_accelerator
panel_binding_parse_accelerator() could return NULL of the unowned panel_binding_parse_accelerator() could return NULL of the unowned
IBus.ProcessKeyEventData with gcc optimization. IBus.ProcessKeyEventData with gcc optimization.
Since Vala does not provice a static local variable, the variable is Since Vala does not provice a static local variable, the variable is
moved to the class member to fix this SEGV. moved to the class member to fix this SEGV.
Also fixed an infinite loop to show a compose preedit in xterm.
Also a NULL preedit is fixed in the first emoji candidate from the Also a NULL preedit is fixed in the first emoji candidate from the
emoji category window. emoji category window.
--- ---
bus/inputcontext.c | 9 +++++++++
bus/panelproxy.c | 38 ++++++++++++++++++++++++++++++++++++--
ui/gtk3/panelbinding.vala | 28 ++++++++++++++++------------ ui/gtk3/panelbinding.vala | 28 ++++++++++++++++------------
1 file changed, 16 insertions(+), 12 deletions(-) 3 files changed, 61 insertions(+), 14 deletions(-)
diff --git a/bus/inputcontext.c b/bus/inputcontext.c
index bf9eafcf..98639a24 100644
--- a/bus/inputcontext.c
+++ b/bus/inputcontext.c
@@ -1730,6 +1730,15 @@ bus_input_context_hide_auxiliary_text (BusInputContext *context)
}
}
+/**
+ * bus_input_context_update_lookup_table:
+ * @context: #BusInputContext
+ * @table: #IBusLookupTable
+ * @visible: %TRUE if the lookup table is visible, otherwise %FALSE.
+ * @is_extension: %TRUE if the lookup table is called by a panel extension.
+ * %FALSE if it's called by an engine.
+ * I.e. is_extension_lookup_table means the owner of the lookup table.
+ */
void
bus_input_context_update_lookup_table (BusInputContext *context,
IBusLookupTable *table,
diff --git a/bus/panelproxy.c b/bus/panelproxy.c
index 1c0fcca2..3e6d5be2 100644
--- a/bus/panelproxy.c
+++ b/bus/panelproxy.c
@@ -743,6 +743,16 @@ _context_update_preedit_text_cb (BusInputContext *context,
g_return_if_fail (panel->focused_context == context);
+ /* The callback is called with X11 applications but
+ * the callback is not called for extensions and panel
+ * extensions are always calls by
+ * bus_panel_proxy_update_preedit_text() directly
+ * because panel extensions foward UpdatePreeditText to
+ * UpdatePreeditTextReceived and it can be an infinite
+ * loop.
+ */
+ if (panel->panel_type != PANEL_TYPE_PANEL)
+ return;
bus_panel_proxy_update_preedit_text (panel,
text,
cursor_pos,
@@ -847,8 +857,31 @@ _context_set_content_type_cb (BusInputContext *context,
bus_panel_proxy_##name (panel); \
}
-DEFINE_FUNCTION (show_preedit_text)
-DEFINE_FUNCTION (hide_preedit_text)
+#define DEFINE_FUNCTION_NO_EXTENSION(name) \
+ static void _context_##name##_cb (BusInputContext *context, \
+ BusPanelProxy *panel) \
+ { \
+ g_assert (BUS_IS_INPUT_CONTEXT (context)); \
+ g_assert (BUS_IS_PANEL_PROXY (panel)); \
+ \
+ g_return_if_fail (panel->focused_context == context); \
+ \
+ /* The callback is called with X11 applications but \
+ * the callback is not called for extensions and panel \
+ * extensions are always calls by \
+ * bus_panel_proxy_update_preedit_text() directly \
+ * because panel extensions foward UpdatePreeditText to \
+ * UpdatePreeditTextReceived and it can be an infinite \
+ * loop. \
+ */ \
+ if (panel->panel_type != PANEL_TYPE_PANEL) \
+ return; \
+ bus_panel_proxy_##name (panel); \
+ }
+
+
+DEFINE_FUNCTION_NO_EXTENSION (show_preedit_text)
+DEFINE_FUNCTION_NO_EXTENSION (hide_preedit_text)
DEFINE_FUNCTION (show_auxiliary_text)
DEFINE_FUNCTION (hide_auxiliary_text)
DEFINE_FUNCTION (show_lookup_table)
@@ -860,6 +893,7 @@ DEFINE_FUNCTION (cursor_down_lookup_table)
DEFINE_FUNCTION (state_changed)
#undef DEFINE_FUNCTION
+#undef DEFINE_FUNCTION_NO_EXTENSION
static const struct {
gchar *name;
diff --git a/ui/gtk3/panelbinding.vala b/ui/gtk3/panelbinding.vala diff --git a/ui/gtk3/panelbinding.vala b/ui/gtk3/panelbinding.vala
index 52b78c17..95115b13 100644 index 52b78c17..95115b13 100644
--- a/ui/gtk3/panelbinding.vala --- a/ui/gtk3/panelbinding.vala

View File

@ -39,7 +39,7 @@
Name: ibus Name: ibus
Version: 1.5.18 Version: 1.5.18
Release: 8%{?dist} Release: 9%{?dist}
Summary: Intelligent Input Bus for Linux OS Summary: Intelligent Input Bus for Linux OS
License: LGPLv2+ License: LGPLv2+
Group: System Environment/Libraries Group: System Environment/Libraries
@ -435,6 +435,10 @@ dconf update || :
%{_datadir}/gtk-doc/html/* %{_datadir}/gtk-doc/html/*
%changelog %changelog
* Fri Jun 29 2018 Takao Fujiwara <tfujiwar@redhat.com> - 1.5.18-9
- Do not use combined characters on preedit for compose keys
- Fixed an infinite loop of extension preedit with xterm
* Wed Jun 27 2018 Takao Fujiwara <tfujiwar@redhat.com> - 1.5.18-8 * Wed Jun 27 2018 Takao Fujiwara <tfujiwar@redhat.com> - 1.5.18-8
- Enable preedit for compose keys - Enable preedit for compose keys
- Fix SEGV in panel_binding_parse_accelerator - Fix SEGV in panel_binding_parse_accelerator