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
From 9b26a4b46fa2635033d315e8babb8c4ca9869898 Mon Sep 17 00:00:00 2001
From 3a68ded197b3ad2e45ac08fe52c0514aff987367 Mon Sep 17 00:00:00 2001
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
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 fixed an infinite loop to show a compose preedit in xterm.
Also a NULL preedit is fixed in the first emoji candidate from the
emoji category window.
---
bus/inputcontext.c | 9 +++++++++
bus/panelproxy.c | 38 ++++++++++++++++++++++++++++++++++++--
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
index 52b78c17..95115b13 100644
--- a/ui/gtk3/panelbinding.vala

View File

@ -39,7 +39,7 @@
Name: ibus
Version: 1.5.18
Release: 8%{?dist}
Release: 9%{?dist}
Summary: Intelligent Input Bus for Linux OS
License: LGPLv2+
Group: System Environment/Libraries
@ -435,6 +435,10 @@ dconf update || :
%{_datadir}/gtk-doc/html/*
%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
- Enable preedit for compose keys
- Fix SEGV in panel_binding_parse_accelerator