diff --git a/ibus-HEAD.patch b/ibus-HEAD.patch index 1eb47eb..45d0eef 100644 --- a/ibus-HEAD.patch +++ b/ibus-HEAD.patch @@ -673,3 +673,553 @@ index 5496c4e..bc1eff4 100644 -- 2.7.4 +From 31ed31e5303c3946f53b035a63d76f5c1e3cd84a Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Mon, 13 Mar 2017 11:43:09 +0900 +Subject: [PATCH] src: Fix ibus_emoji_dict_load() + +R=Shawn.P.Huang@gmail.com + +Review URL: https://codereview.appspot.com/320350043 +--- + configure.ac | 3 ++- + src/emoji-parser.c | 6 ++++-- + src/ibusemoji.c | 6 +++--- + 3 files changed, 9 insertions(+), 6 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 027c027..369485c 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -620,7 +620,8 @@ fi + + AC_ARG_WITH(emoji-json-file, + AS_HELP_STRING([--with-emoji-json-file[=DIR/emoji.json]], +- [Set emoji.json. (default: "/usr/lib/node_modules/emojione/emoji.json")]), ++ [Set emoji.json. (default: "/usr/lib/node_modules/emojione/emoji.json") ++ You can get emoji.json with "npm install -g emojione".]), + EMOJI_JSON_FILE=$with_emoji_json_file, + EMOJI_JSON_FILE="/usr/lib/node_modules/emojione/emoji.json" + ) +diff --git a/src/emoji-parser.c b/src/emoji-parser.c +index c5af42c..5965309 100644 +--- a/src/emoji-parser.c ++++ b/src/emoji-parser.c +@@ -1,7 +1,7 @@ + /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ + /* vim:set et sts=4: */ + /* ibus - The Input Bus +- * Copyright (C) 2016 Takao Fujiwara ++ * Copyright (C) 2016-2017 Takao Fujiwara + * Copyright (C) 2016 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or +@@ -20,9 +20,11 @@ + * USA + */ + +-/* Convert ../data/annotations/en.xml and ++/* Convert /usr/share/unicode/cldr/common/annotations/*.xml and + * /usr/lib/node_modules/emojione/emoji.json + * to the dictionary file which look up the Emoji from the annotation. ++ * Get *.xml from https://github.com/fujiwarat/cldr-emoji-annotation ++ * or http://www.unicode.org/repos/cldr/trunk/common/annotations . + * Get emoji.json with 'npm install -g emojione'. + * en.xml is used for the Unicode annotations and emoji.json is used + * for the aliases_ascii, e.g. ":)", and category, e.g. "people". +diff --git a/src/ibusemoji.c b/src/ibusemoji.c +index 8d88704..996d136 100644 +--- a/src/ibusemoji.c ++++ b/src/ibusemoji.c +@@ -431,10 +431,10 @@ ibus_emoji_dict_load (const gchar *path) + GHashTable *dict = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, +- free_dict_words); ++ g_object_unref); + + for (l = list; l; l = l->next) { +- IBusEmojiData *data = list->data; ++ IBusEmojiData *data = l->data; + if (!IBUS_IS_EMOJI_DATA (data)) { + g_warning ("Your dict format is no longer supported.\n" + "Need to create the dictionaries again."); +@@ -442,7 +442,7 @@ ibus_emoji_dict_load (const gchar *path) + } + g_hash_table_insert (dict, + g_strdup (ibus_emoji_data_get_emoji (data)), +- data); ++ g_object_ref_sink (data)); + } + + g_slist_free (list); +-- +2.9.3 + +From c580845167b54ccab76d8b72bdc797ef8d64d554 Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Mon, 13 Mar 2017 11:58:06 +0900 +Subject: [PATCH] ui/gtk3: Fix emoji text entry cusor position + +Focus on emoji text entry by default +Remove internal text buffer and use Gtk.Entry buffer instead. +Implement cusor left, right, home, end on emoji annotation preedit. + +Review URL: https://codereview.appspot.com/313710043 +--- + ui/gtk3/emojier.vala | 104 +++++++++++++++++++++++++++++++++------------------ + 1 file changed, 68 insertions(+), 36 deletions(-) + +diff --git a/ui/gtk3/emojier.vala b/ui/gtk3/emojier.vala +index bc1eff4..8cecea8 100644 +--- a/ui/gtk3/emojier.vala ++++ b/ui/gtk3/emojier.vala +@@ -75,7 +75,10 @@ class IBusEmojier : Gtk.Window { + row_homogeneous : false, + vexpand : true, + halign : Gtk.Align.FILL, +- valign : Gtk.Align.FILL ++ valign : Gtk.Align.FILL, ++ row_spacing : 5, ++ column_spacing : 5, ++ border_width : 2 + ); + } + } +@@ -190,7 +193,6 @@ class IBusEmojier : Gtk.Window { + private CategoryType m_current_category_type = CategoryType.EMOJI; + private bool m_is_running = false; + private string m_input_context_path = ""; +- private GLib.StringBuilder m_buffer_string; + private GLib.MainLoop? m_loop; + private string? m_result; + private GLib.SList m_lang_list; +@@ -288,11 +290,9 @@ class IBusEmojier : Gtk.Window { + m_entry.set_placeholder_text(_("Type annotation or choose emoji")); + m_vbox.add(m_entry); + m_entry.changed.connect(() => { +- m_buffer_string.assign(m_entry.get_text()); +- update_cadidate_window(); ++ update_candidate_window(); + }); + m_entry.icon_release.connect((icon_pos, event) => { +- m_buffer_string.erase(); + hide_candidate_panel(); + }); + +@@ -303,7 +303,6 @@ class IBusEmojier : Gtk.Window { + Atk.Object obj = m_entry.get_accessible(); + obj.set_role (Atk.Role.STATUSBAR); + +- m_buffer_string = new StringBuilder(); + grab_focus(); + + // The constructor of IBus.LookupTable does not support more than +@@ -680,11 +679,16 @@ class IBusEmojier : Gtk.Window { + buttons_hbox.show_all(); + } + +- private bool check_unicode_point(bool check_xdigit_only) { +- m_unicode_point = null; ++ private bool check_unicode_point(string? annotation=null) { ++ bool check_xdigit_only = true; ++ if (annotation == null) { ++ annotation = m_entry.get_text(); ++ m_unicode_point = null; ++ check_xdigit_only = false; ++ } + GLib.StringBuilder buff = new GLib.StringBuilder(); +- for (int i = 0; i < m_buffer_string.str.char_count(); i++) { +- unichar ch = m_buffer_string.str.get_char(i); ++ for (int i = 0; i < annotation.char_count(); i++) { ++ unichar ch = annotation.get_char(i); + if (ch == 0) + return false; + if (!ch.isxdigit()) +@@ -704,7 +708,7 @@ class IBusEmojier : Gtk.Window { + return true; + } + +- public void update_cadidate_window() { ++ public void update_candidate_window() { + string annotation = m_entry.get_text(); + if (annotation.length == 0) { + hide_candidate_panel(); +@@ -716,7 +720,7 @@ class IBusEmojier : Gtk.Window { + return; + } + // Call check_unicode_point() to get m_unicode_point +- check_unicode_point(false); ++ check_unicode_point(); + unowned GLib.SList? emojis = + m_annotation_to_emojis_dict.lookup(annotation); + if (emojis == null && m_unicode_point == null) { +@@ -725,7 +729,7 @@ class IBusEmojier : Gtk.Window { + } + m_lookup_table.clear(); + // Call check_unicode_point() to update m_lookup_table +- check_unicode_point(false); ++ check_unicode_point(); + foreach (unowned string emoji in emojis) { + IBus.Text text = new IBus.Text.from_string(emoji); + m_lookup_table.append_candidate(text); +@@ -760,9 +764,6 @@ class IBusEmojier : Gtk.Window { + }); + } + EGrid grid = new EGrid(); +- grid.set_row_spacing(5); +- grid.set_column_spacing(5); +- grid.set_border_width(2); + int n = 0; + for (uint i = page_start_pos; i < page_end_pos; i++) { + IBus.Text candidate = m_lookup_table.get_candidate(i); +@@ -878,14 +879,11 @@ class IBusEmojier : Gtk.Window { + private bool if_in_range_of_lookup(uint keyval) { + if (!m_candidate_panel_is_visible) + return false; +- string backup_annotation = m_buffer_string.str.dup(); ++ StringBuilder buffer_string = new StringBuilder(m_entry.get_text()); + unichar ch = IBus.keyval_to_unicode (keyval); +- m_buffer_string.append_unichar(ch); +- if (check_unicode_point(true)) { +- m_buffer_string.assign(backup_annotation); ++ buffer_string.append_unichar(ch); ++ if (check_unicode_point(buffer_string.str)) + return false; +- } +- m_buffer_string.assign(backup_annotation); + if (keyval < Gdk.Key.@0 || keyval > Gdk.Key.@9) + return false; + if (keyval == Gdk.Key.@0) +@@ -958,6 +956,18 @@ class IBusEmojier : Gtk.Window { + show_category_list(); + } + ++ private void entry_enter_keyval(uint keyval) { ++ unichar ch = IBus.keyval_to_unicode(keyval); ++ if (!ch.isgraph()) ++ return; ++ string str = ch.to_string(); ++ ++ // what gtk_entry_commit_cb() do ++ int pos = m_entry.get_position(); ++ m_entry.insert_text(str, -1, ref pos); ++ m_entry.set_position(pos); ++ } ++ + public string run(Gdk.Event event, + string input_context_path) { + assert (m_loop == null); +@@ -972,7 +982,7 @@ class IBusEmojier : Gtk.Window { + resize(1, 1); + + m_entry.set_text(""); +- m_buffer_string.erase(); ++ m_entry.grab_focus(); + + Gdk.Device device = event.get_device(); + if (device == null) { +@@ -1070,12 +1080,12 @@ class IBusEmojier : Gtk.Window { + m_current_category_type = CategoryType.EMOJI; + show_candidate_panel(); + return true; +- } else if (m_buffer_string.str.length == 0) { ++ } else if (m_entry.get_text().length == 0) { + m_loop.quit(); + hide_candidate_panel(); + return true; + } +- m_buffer_string.erase(); ++ m_entry.delete_text(0, -1); + break; + case Gdk.Key.Return: + if (m_candidate_panel_is_visible) { +@@ -1094,14 +1104,14 @@ class IBusEmojier : Gtk.Window { + } + return true; + case Gdk.Key.BackSpace: +- if (m_buffer_string.len > 0) +- m_buffer_string.erase(m_buffer_string.len - 1); ++ if (m_entry.get_text().len() > 0) { ++ GLib.Signal.emit_by_name(m_entry, "backspace"); ++ } + break; + case Gdk.Key.space: + case Gdk.Key.KP_Space: + if ((modifiers & Gdk.ModifierType.SHIFT_MASK) != 0) { +- unichar ch = IBus.keyval_to_unicode (keyval); +- m_buffer_string.append_unichar(ch); ++ entry_enter_keyval(keyval); + break; + } + if (m_candidate_panel_is_visible) { +@@ -1120,6 +1130,12 @@ class IBusEmojier : Gtk.Window { + show_candidate_panel(); + return true; + } ++ if (m_entry.get_text().len() > 0) { ++ GLib.Signal.emit_by_name(m_entry, "move-cursor", ++ Gtk.MovementStep.VISUAL_POSITIONS, ++ 1, false); ++ return true; ++ } + break; + case Gdk.Key.Left: + if (m_candidate_panel_is_visible) { +@@ -1128,6 +1144,12 @@ class IBusEmojier : Gtk.Window { + show_candidate_panel(); + return true; + } ++ if (m_entry.get_text().len() > 0) { ++ GLib.Signal.emit_by_name(m_entry, "move-cursor", ++ Gtk.MovementStep.VISUAL_POSITIONS, ++ -1, false); ++ return true; ++ } + break; + case Gdk.Key.Down: + if (m_candidate_panel_is_visible) +@@ -1157,17 +1179,27 @@ class IBusEmojier : Gtk.Window { + return true; + } + break; +- default: +- unichar ch = IBus.keyval_to_unicode(keyval); +- if (!ch.isgraph()) ++ case Gdk.Key.Home: ++ if (m_entry.get_text().len() > 0) { ++ GLib.Signal.emit_by_name(m_entry, "move-cursor", ++ Gtk.MovementStep.DISPLAY_LINE_ENDS, ++ -1, false); ++ return true; ++ } ++ break; ++ case Gdk.Key.End: ++ if (m_entry.get_text().len() > 0) { ++ GLib.Signal.emit_by_name(m_entry, "move-cursor", ++ Gtk.MovementStep.DISPLAY_LINE_ENDS, ++ 1, false); + return true; +- m_buffer_string.append_unichar(ch); ++ } ++ break; ++ default: ++ entry_enter_keyval(keyval); + break; + } + +- string annotation = m_buffer_string.str; +- m_entry.set_text(annotation); +- + return true; + } + +-- +2.9.3 + +From fbe3de1789c73a8a175a451b2a6b967f5d3c6514 Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Mon, 13 Mar 2017 12:08:21 +0900 +Subject: [PATCH] src: Update emoji-parser to treat tts as emoji + description + +unicode annotation xml files have a 'tts' attribute and seem +it is used as the emoji descriptions instead of emoji annotations. +This can show the translated descriptions. + +R=Shawn.P.Huang@gmail.com + +Review URL: https://codereview.appspot.com/319480043 +--- + src/emoji-parser.c | 26 +++++++++++++++++++------- + src/ibusemoji.c | 16 +++++++++++++--- + src/ibusemoji.h | 11 +++++++++++ + ui/gtk3/emojier.vala | 17 ++++++++++++++--- + 4 files changed, 57 insertions(+), 13 deletions(-) + +diff --git a/src/emoji-parser.c b/src/emoji-parser.c +index 5965309..8ff04f1 100644 +--- a/src/emoji-parser.c ++++ b/src/emoji-parser.c +@@ -43,6 +43,7 @@ struct _EmojiData { + GSList *annotations; + gboolean is_annotation; + gchar *description; ++ gboolean is_tts; + gchar *category; + GSList *list; + }; +@@ -97,6 +98,8 @@ update_emoji_list (EmojiData *data) + (GCopyFunc) g_strdup, + NULL)); + } ++ if (data->description) ++ ibus_emoji_data_set_description (emoji, data->description); + } else { + IBusEmojiData *emoji = + ibus_emoji_data_new ("emoji", +@@ -149,13 +152,12 @@ unicode_annotations_start_element_cb (GMarkupParseContext *context, + data->emoji = g_strdup (value); + } + } +- else if (g_strcmp0 (attribute, "tts") == 0) { +- GSList *duplicated = g_slist_find_custom (data->annotations, +- value, +- (GCompareFunc) g_strcmp0); +- if (duplicated == NULL) { +- data->annotations = g_slist_prepend (data->annotations, +- g_strdup (value)); ++ /* tts seems 'text to speach' and it would be a description ++ * instead of annotation. ++ */ ++ else if (g_strcmp0 (attribute, "type") == 0) { ++ if (g_strcmp0 (value, "tts") == 0) { ++ data->is_tts = TRUE; + } + } + } +@@ -177,6 +179,7 @@ unicode_annotations_end_element_cb (GMarkupParseContext *context, + + update_emoji_list (data); + data->is_annotation = FALSE; ++ data->is_tts = FALSE; + } + + void +@@ -194,6 +197,15 @@ unicode_annotations_text_cb (GMarkupParseContext *context, + g_assert (data != NULL); + if (!data->is_annotation) + return; ++ if (data->is_tts) { ++ if (data->description) { ++ g_warning ("Duplicated 'tts' is found: %s: %s", ++ data->description, text); ++ g_clear_pointer (&data->description, g_free); ++ } ++ data->description = g_strdup (text); ++ return; ++ } + annotations = g_strsplit (text, " | ", -1); + for (i = 0; (annotation = annotations[i]) != NULL; i++) { + GSList *duplicated = g_slist_find_custom (data->annotations, +diff --git a/src/ibusemoji.c b/src/ibusemoji.c +index 996d136..c61cd70 100644 +--- a/src/ibusemoji.c ++++ b/src/ibusemoji.c +@@ -29,7 +29,7 @@ + #include "ibusinternal.h" + + #define IBUS_EMOJI_DATA_MAGIC "IBusEmojiData" +-#define IBUS_EMOJI_DATA_VERSION (1) ++#define IBUS_EMOJI_DATA_VERSION (2) + + enum { + PROP_0 = 0, +@@ -128,7 +128,7 @@ ibus_emoji_data_class_init (IBusEmojiDataClass *class) + "emoji description", + "The emoji description", + "", +- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); ++ G_PARAM_READWRITE)); + + /** + * IBusEmojiData:category: +@@ -352,6 +352,16 @@ ibus_emoji_data_get_description (IBusEmojiData *emoji) + return emoji->priv->description; + } + ++void ++ibus_emoji_data_set_description (IBusEmojiData *emoji, ++ const gchar *description) ++{ ++ g_return_if_fail (IBUS_IS_EMOJI_DATA (emoji)); ++ ++ g_free (emoji->priv->description); ++ emoji->priv->description = g_strdup (description); ++} ++ + const gchar * + ibus_emoji_data_get_category (IBusEmojiData *emoji) + { +@@ -541,7 +551,7 @@ ibus_emoji_data_load (const gchar *path) + goto out_load_cache; + } + +- if (version != IBUS_EMOJI_DATA_VERSION) { ++ if (version > IBUS_EMOJI_DATA_VERSION) { + g_warning ("cache version is different: %u != %u", + version, IBUS_EMOJI_DATA_VERSION); + goto out_load_cache; +diff --git a/src/ibusemoji.h b/src/ibusemoji.h +index 3fd09a9..eb24fdd 100644 +--- a/src/ibusemoji.h ++++ b/src/ibusemoji.h +@@ -134,6 +134,17 @@ void ibus_emoji_data_set_annotations (IBusEmojiData *emoji, + const gchar * ibus_emoji_data_get_description (IBusEmojiData *emoji); + + /** ++ * ibus_emoji_data_set_description: ++ * @emoji : An #IBusEmojiData ++ * @description: An emoji description ++ * ++ * Sets the description in #IBusEmojiData. ++ */ ++void ibus_emoji_data_set_description (IBusEmojiData *emoji, ++ const gchar *description); ++ ++ ++/** + * ibus_emoji_data_get_category: + * @emoji : An #IBusEmojiData + * +diff --git a/ui/gtk3/emojier.vala b/ui/gtk3/emojier.vala +index 8cecea8..5e126e9 100644 +--- a/ui/gtk3/emojier.vala ++++ b/ui/gtk3/emojier.vala +@@ -370,8 +370,14 @@ class IBusEmojier : Gtk.Window { + private void reload_emoji_dict() { + init_emoji_dict(); + make_emoji_dict("en"); +- if (m_current_lang_id != "en") ++ if (m_current_lang_id != "en") { ++ var lang_ids = m_current_lang_id.split("_"); ++ if (lang_ids.length > 1) { ++ string sub_id = lang_ids[0]; ++ make_emoji_dict(sub_id); ++ } + make_emoji_dict(m_current_lang_id); ++ } + loaded_emoji_dict(); + } + +@@ -393,8 +399,8 @@ class IBusEmojier : Gtk.Window { + if (emoji_list == null) + return; + foreach (IBus.EmojiData data in emoji_list) { +- update_annotation_to_emojis_dict(data); + update_emoji_to_data_dict(data, lang); ++ update_annotation_to_emojis_dict(data); + update_category_to_emojis_dict(data, lang); + } + GLib.List annotations = +@@ -434,11 +440,16 @@ class IBusEmojier : Gtk.Window { + unowned IBus.EmojiData? en_data = + m_emoji_to_data_dict.lookup(emoji); + if (en_data == null) { +- warning("No IBusEmojiData for English: %s".printf(emoji)); + m_emoji_to_data_dict.insert(emoji, data); + return; + } ++ string trans_description = data.get_description(); ++ en_data.set_description(trans_description); + unowned GLib.SList annotations = data.get_annotations(); ++ var words = trans_description.split(" "); ++ // If the description has less than 3 words, add it to annotations ++ if (words.length < 3) ++ annotations.append(trans_description); + unowned GLib.SList en_annotations + = en_data.get_annotations(); + foreach (string annotation in en_annotations) { +-- +2.9.3 + diff --git a/ibus.spec b/ibus.spec index f02d1c6..3166733 100644 --- a/ibus.spec +++ b/ibus.spec @@ -28,7 +28,7 @@ Name: ibus Version: 1.5.15 -Release: 2%{?dist} +Release: 3%{?dist} Summary: Intelligent Input Bus for Linux OS License: LGPLv2+ Group: System Environment/Libraries @@ -426,6 +426,14 @@ gtk-query-immodules-3.0-%{__isa_bits} --update-cache &> /dev/null || : %{_datadir}/gtk-doc/html/* %changelog +* Mon Mar 13 2017 Takao Fujiwara - 1.5.15-3 +- Emoji dialog enhancements and bug fixes + Fixed ibus_emoji_dict_load() API. + Focus on emoji text entry by default + Removed internal text buffer and use Gtk.Entry buffer instead. + Implemented cursor left, right, home, end on emoji annotation preedit. + Show localized emoji description from tts in emoji xml. + * Thu Mar 09 2017 Takao Fujiwara - 1.5.15-2 - Added ibus-HEAD.patch to get upstream patches Fixed ibus_emojier_run() SIGABRT with `ibus emoji`