From 49a428b52e0a4c23776861364c6d77d07d2b26fe Mon Sep 17 00:00:00 2001 From: Takao Fujiwara Date: May 29 2017 03:36:17 +0000 Subject: Added ctrl-c,v,x for annotations and ctrl-shift-c for emoji - Added Malay and Mongolian keymaps - Made all emoji dicts to fully qualified --- diff --git a/ibus-HEAD.patch b/ibus-HEAD.patch index e69de29..6392feb 100644 --- a/ibus-HEAD.patch +++ b/ibus-HEAD.patch @@ -0,0 +1,590 @@ +From 4fe3050efa7335f82870fb1d5a1d170d20afc160 Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Mon, 22 May 2017 12:04:28 +0900 +Subject: [PATCH] configure: Change relative paths to absolute ones + +BUG=https://github.com/ibus/ibus/issues/1926 +R=Shawn.P.Huang@gmail.com + +Review URL: https://codereview.appspot.com/322990043 +--- + configure.ac | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/configure.ac b/configure.ac +index 2cc96d1..cb48ad4 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -634,10 +634,21 @@ if test x"$enable_emoji_dict" = x"yes"; then + if test ! -f $UNICODE_EMOJI_DIR/emoji-test.txt ; then + AC_MSG_ERROR(Not found $UNICODE_EMOJI_DIR/emoji-test.txt. You can get \ + the emoji files from http://www.unicode.org/Public/emoji/4.0/) ++ else ++ # POSIX SHELL has no ${FOO:0:1} ++ head=`echo "$UNICODE_EMOJI_DIR" | cut -c1`; ++ if test $head != "/" ; then ++ UNICODE_EMOJI_DIR=`realpath "$UNICODE_EMOJI_DIR"` ++ fi + fi + if test ! -f $EMOJI_ANNOTATION_DIR/en.xml ; then + AC_MSG_ERROR(Not found $EMOJI_ANNOTATION_DIR/en.xml. You can get \ + https://github.com/fujiwarat/cldr-emoji-annotation) ++ else ++ head=`echo "$EMOJI_ANNOTATION_DIR" | cut -c1`; ++ if test $head != "/" ; then ++ EMOJI_ANNOTATION_DIR=`realpath "$EMOJI_ANNOTATION_DIR"` ++ fi + fi + enable_emoji_dict="yes (enabled, use --disable-emoji-dict to disable)" + fi +-- +2.9.3 + +From 44d053577a6ac115f3fd3b7beb7bdd65da81aa64 Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Wed, 24 May 2017 11:52:19 +0900 +Subject: [PATCH] engine: Add Malay and Mongolian keymaps + +R=Shawn.P.Huang@gmail.com + +Review URL: https://codereview.appspot.com/325790043 +--- + engine/simple.xml.in | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +diff --git a/engine/simple.xml.in b/engine/simple.xml.in +index c08000f..f35d7a5 100644 +--- a/engine/simple.xml.in ++++ b/engine/simple.xml.in +@@ -706,5 +706,27 @@ + ibus-keyboard + 1 + ++ ++ xkb:my::msa ++ ms ++ GPL ++ Peng Huang <shawn.p.huang@gmail.com> ++ my ++ Malay (Jawi) ++ Malay (Jawi) ++ ibus-keyboard ++ 1 ++ ++ ++ xkb:mn::mon ++ mn ++ GPL ++ Peng Huang <shawn.p.huang@gmail.com> ++ mn ++ Mongolian ++ Mongolian ++ ibus-keyboard ++ 1 ++ + + +-- +2.9.3 + +From 081d09f1a927f459dacda3bcc59a1678ca2f9a95 Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Mon, 29 May 2017 11:54:31 +0900 +Subject: [PATCH] ui/gtk3: Emojier supports Ctrl-c,v,x and Ctrl-Shift-c + +Ctrl-[c|v|x] copy, paste, or cut the emoji annotatons. +Ctrl-Shift-c copies the selected emoji. +Also Ctrl-Backspace is implemented to delete an annotation word. +Also updated ibus-emoji.7.in man page. + +R=penghuang@google.com + +Review URL: https://codereview.appspot.com/316650043 +--- + ui/gtk3/emojier.vala | 58 +++++++++++++++++++++++++++++++++++++++++++++++-- + ui/gtk3/ibus-emoji.7.in | 11 ++++++++++ + 2 files changed, 67 insertions(+), 2 deletions(-) + +diff --git a/ui/gtk3/emojier.vala b/ui/gtk3/emojier.vala +index d0d69ed..1d105fd 100644 +--- a/ui/gtk3/emojier.vala ++++ b/ui/gtk3/emojier.vala +@@ -1392,7 +1392,26 @@ class IBusEmojier : Gtk.ApplicationWindow { + return true; + case Gdk.Key.BackSpace: + if (m_entry.get_text().len() > 0) { +- GLib.Signal.emit_by_name(m_entry, "backspace"); ++ if ((modifiers & Gdk.ModifierType.CONTROL_MASK) != 0) { ++ GLib.Signal.emit_by_name(m_entry, "delete-from-cursor", ++ Gtk.DeleteType.WORD_ENDS, -1); ++ } else { ++ GLib.Signal.emit_by_name(m_entry, "backspace"); ++ } ++ return true; ++ } ++ break; ++ case Gdk.Key.Delete: ++ case Gdk.Key.KP_Delete: ++ if (m_entry.get_text().len() > 0) { ++ if ((modifiers & Gdk.ModifierType.CONTROL_MASK) != 0) { ++ GLib.Signal.emit_by_name(m_entry, "delete-from-cursor", ++ Gtk.DeleteType.WORD_ENDS, 1); ++ } else { ++ GLib.Signal.emit_by_name(m_entry, "delete-from-cursor", ++ Gtk.DeleteType.CHARS, 1); ++ } ++ return true; + } + break; + case Gdk.Key.space: +@@ -1445,6 +1464,10 @@ class IBusEmojier : Gtk.ApplicationWindow { + if (key_press_cursor_home_end(keyval, modifiers)) + return true; + break; ++ case Gdk.Key.Insert: ++ case Gdk.Key.KP_Insert: ++ GLib.Signal.emit_by_name(m_entry, "toggle-overwrite"); ++ return true; + } + + if ((modifiers & Gdk.ModifierType.CONTROL_MASK) != 0) { +@@ -1470,8 +1493,13 @@ class IBusEmojier : Gtk.ApplicationWindow { + return true; + break; + case Gdk.Key.u: +- if (key_press_escape()) ++ if (m_entry.get_text().len() > 0) { ++ GLib.Signal.emit_by_name(m_entry, ++ "delete-from-cursor", ++ Gtk.DeleteType.PARAGRAPH_ENDS, ++ -1); + return true; ++ } + break; + case Gdk.Key.a: + if (m_entry.get_text().len() > 0) { +@@ -1479,6 +1507,32 @@ class IBusEmojier : Gtk.ApplicationWindow { + return true; + } + break; ++ case Gdk.Key.x: ++ if (m_entry.get_text().len() > 0) { ++ GLib.Signal.emit_by_name(m_entry, "cut-clipboard"); ++ return true; ++ } ++ break; ++ case Gdk.Key.C: ++ case Gdk.Key.c: ++ if ((modifiers & Gdk.ModifierType.SHIFT_MASK) != 0) { ++ if (m_candidate_panel_is_visible) { ++ uint index = m_lookup_table.get_cursor_pos(); ++ var text = m_lookup_table.get_candidate(index).text; ++ Gtk.Clipboard clipboard = ++ Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD); ++ clipboard.set_text(text, -1); ++ clipboard.store(); ++ return true; ++ } ++ } else if (m_entry.get_text().len() > 0) { ++ GLib.Signal.emit_by_name(m_entry, "copy-clipboard"); ++ return true; ++ } ++ break; ++ case Gdk.Key.v: ++ GLib.Signal.emit_by_name(m_entry, "paste-clipboard"); ++ return true; + } + return false; + } +diff --git a/ui/gtk3/ibus-emoji.7.in b/ui/gtk3/ibus-emoji.7.in +index a5045f6..4ee8636 100644 +--- a/ui/gtk3/ibus-emoji.7.in ++++ b/ui/gtk3/ibus-emoji.7.in +@@ -83,6 +83,17 @@ Move to the next or previous page in the emoji list. + \fBHead, End, Control-h or Control-e\fR + Select the first or last emoji on the list if an annotation is not typed. + Otherwise move the cursor to the head or end in the typed annotation. ++.TP ++\fBControl-u\fR ++Erase the typed annotation. ++.TP ++\fBControl-x or Control-v or Control-c\fR ++Cut the selected annotation to the clipboard with Control-x. Paste ++the contents of the clipboard into the annotation entry with Control-v. ++Copy the selected annotation to the clipboard with Control-c. ++.TP ++\fBControl-Shift-c\fR ++Copy the selected emoji to the clipboard. + + .SH BUGS + If you find a bug, please report it at https://github.com/ibus/ibus/issues +-- +2.9.3 + +From ad80999f5a10faee1a665a2232e1cf60be901cc8 Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Mon, 29 May 2017 12:03:41 +0900 +Subject: [PATCH] Make all emoji dicts for fully qualified + +Currently only emoji-en.dict enables fully qualified since it imports +emoji-test.txt and it causes to hardly compare emojis between +emoji-en.dict and emoji-$lang.dict when m_show_emoji_variant +is enabled. E.g. U+1F3CC-FE0F-200D-2642-FE0F +Now emoji-$lang.dict also import emoji-test.txt and enables +fully qualified. + +R=penghuang@google.com + +Review URL: https://codereview.appspot.com/323860043 +--- + src/Makefile.am | 1 + + src/emoji-parser.c | 167 +++++++++++++++++++++++++++++++++++++++++++++------ + src/ibusemoji.c | 2 +- + ui/gtk3/emojier.vala | 34 +++++------ + 4 files changed, 169 insertions(+), 35 deletions(-) + +diff --git a/src/Makefile.am b/src/Makefile.am +index 27cd168..e7bc8be 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -263,6 +263,7 @@ dicts/emoji-en.dict: emoji-parser + --out $@; \ + else \ + $(builddir)/emoji-parser \ ++ --unicode-emoji-dir $(UNICODE_EMOJI_DIR) \ + --xml $(EMOJI_ANNOTATION_DIR)/$$f.xml \ + $$xml_derived_option \ + --out dicts/emoji-$$f.dict; \ +diff --git a/src/emoji-parser.c b/src/emoji-parser.c +index 5e6155b..fe3e4ef 100644 +--- a/src/emoji-parser.c ++++ b/src/emoji-parser.c +@@ -31,12 +31,20 @@ + * ASCII emoji annotations are saved in ../data/annotations/en_ascii.xml + */ + ++#ifdef HAVE_CONFIG_H ++#include ++#endif ++ + #include + + #ifdef HAVE_JSON_GLIB1 + #include + #endif + ++#ifdef HAVE_LOCALE_H ++#include ++#endif ++ + #include + + #include "ibusemoji.h" +@@ -65,8 +73,73 @@ struct _EmojiData { + EmojiDataSearchType search_type; + }; + ++typedef struct _NoTransData NoTransData; ++struct _NoTransData { ++ const gchar *xml_file; ++ const gchar *xml_derived_file; ++ GSList *emoji_list; ++}; ++ + static gchar *unicode_emoji_version; + ++ ++static void ++init_annotations (IBusEmojiData *emoji, ++ gpointer user_data) ++{ ++ g_return_if_fail (IBUS_IS_EMOJI_DATA (emoji)); ++ ibus_emoji_data_set_annotations (emoji, NULL); ++ ibus_emoji_data_set_description (emoji, ""); ++} ++ ++static void ++check_no_trans (IBusEmojiData *emoji, ++ NoTransData *no_trans_data) ++{ ++ const gchar *str = NULL; ++ g_return_if_fail (IBUS_IS_EMOJI_DATA (emoji)); ++ if (ibus_emoji_data_get_annotations (emoji) != NULL) ++ return; ++ str = ibus_emoji_data_get_emoji (emoji); ++ if (g_getenv ("IBUS_EMOJI_PARSER_DEBUG") != NULL) { ++ gchar *basename = NULL; ++ if (no_trans_data->xml_file) ++ basename = g_path_get_basename (no_trans_data->xml_file); ++ else if (no_trans_data->xml_derived_file) ++ basename = g_path_get_basename (no_trans_data->xml_derived_file); ++ else ++ basename = g_strdup ("WRONG FILE"); ++ g_warning ("Not found emoji %s in the file %s", str, basename); ++ g_free (basename); ++ } ++ no_trans_data->emoji_list = ++ g_slist_append (no_trans_data->emoji_list, g_strdup (str)); ++} ++ ++int ++strcmp_ibus_emoji_data_str (IBusEmojiData *emoji, ++ const gchar *str) ++{ ++ g_return_val_if_fail (IBUS_IS_EMOJI_DATA (emoji), -1); ++ return g_strcmp0 (ibus_emoji_data_get_emoji (emoji), str); ++} ++ ++static void ++delete_emoji_from_list (const gchar *str, ++ GSList **list) ++{ ++ IBusEmojiData *emoji; ++ ++ g_return_if_fail (list != NULL); ++ GSList *p = g_slist_find_custom (*list, ++ str, ++ (GCompareFunc)strcmp_ibus_emoji_data_str); ++ g_return_if_fail (p != NULL); ++ emoji = p->data; ++ *list = g_slist_remove (*list, emoji); ++ g_object_unref (emoji); ++} ++ + static void + reset_emoji_element (EmojiData *data) + { +@@ -79,6 +152,13 @@ reset_emoji_element (EmojiData *data) + g_clear_pointer (&data->description, g_free); + } + ++/** ++ * strcmp_novariant: ++ * ++ * Return 0 between non-fully-qualified and fully-qualified emojis. ++ * E.g. U+1F3CC-200D-2642 and U+1F3CC-FE0F-200D-2642-FE0F ++ * in case @a_variant or @b_variant == U+FE0F ++ */ + gint + strcmp_novariant (const gchar *a, + const gchar *b, +@@ -86,40 +166,54 @@ strcmp_novariant (const gchar *a, + gunichar b_variant) + { + gint retval; +- gchar *p = NULL; + GString *buff = NULL;; ++ gchar *head = NULL; ++ gchar *p; ++ gchar *variant = NULL; + gchar *substr = NULL; + + if (a_variant > 0) { +- if ((p = g_utf8_strchr (a, -1, a_variant)) != NULL) { ++ if (g_utf8_strchr (a, -1, a_variant) != NULL) { + buff = g_string_new (NULL); +- if (a != p) { +- substr = g_strndup (a, p - a); +- g_string_append (buff, substr); +- g_free (substr); ++ p = head = g_strdup (a); ++ while (*p != '\0') { ++ if ((variant = g_utf8_strchr (p, -1, a_variant)) == NULL) { ++ g_string_append (buff, p); ++ break; ++ } ++ if (p != variant) { ++ substr = g_strndup (p, variant - p); ++ g_string_append (buff, substr); ++ g_free (substr); ++ } ++ p = g_utf8_next_char (variant); + } +- p = g_utf8_next_char (p); +- if (*p != '\0') +- g_string_append (buff, p); + retval = g_strcmp0 (buff->str, b); + g_string_free (buff, TRUE); ++ g_free (head); + return retval; + } else { + return -1; + } + } else if (b_variant > 0) { +- if ((p = g_utf8_strchr (b, -1, b_variant)) != NULL) { ++ if (g_utf8_strchr (b, -1, b_variant) != NULL) { + buff = g_string_new (NULL); +- if (b != p) { +- substr = g_strndup (b, p - b); +- g_string_append (buff, substr); +- g_free (substr); ++ p = head = g_strdup (b); ++ while (*p != '\0') { ++ if ((variant = g_utf8_strchr (p, -1, b_variant)) == NULL) { ++ g_string_append (buff, p); ++ break; ++ } ++ if (p != variant) { ++ substr = g_strndup (p, variant - p); ++ g_string_append (buff, substr); ++ g_free (substr); ++ } ++ p = g_utf8_next_char (variant); + } +- p = g_utf8_next_char (p); +- if (*p != '\0') +- g_string_append (buff, p); + retval = g_strcmp0 (a, buff->str); + g_string_free (buff, TRUE); ++ g_free (head); + return retval; + } else { + return -1; +@@ -1117,6 +1211,12 @@ main (int argc, char *argv[]) + GOptionContext *context; + GError *error = NULL; + GSList *list = NULL; ++ gboolean is_en = TRUE; ++ ++#ifdef HAVE_LOCALE_H ++ /* To output emoji warnings. */ ++ setlocale (LC_ALL, ""); ++#endif + + prgname = g_path_get_basename (argv[0]); + g_set_prgname (prgname); +@@ -1144,12 +1244,45 @@ main (int argc, char *argv[]) + #endif + if (emoji_dir) + unicode_emoji_parse_dir (emoji_dir, &list); ++ if (list) { ++#define CHECK_IS_EN(file) if ((file)) { \ ++ gchar *basename = g_path_get_basename ((file)); \ ++ is_en = (g_ascii_strncasecmp (basename, "en.", 3) == 0) ? \ ++ TRUE : FALSE; \ ++ g_free (basename); \ ++} ++ ++ CHECK_IS_EN(xml_derived_file); ++ CHECK_IS_EN(xml_file); ++#undef CHECK_IS_EN ++ ++ /* Use English emoji-test.txt to get fully-qualified. */ ++ if (!is_en) ++ g_slist_foreach (list, (GFunc)init_annotations, NULL); ++ } + if (xml_file) + unicode_annotations_parse_xml_file (xml_file, &list, FALSE); + if (xml_derived_file) + unicode_annotations_parse_xml_file (xml_derived_file, &list, TRUE); + if (xml_ascii_file) + unicode_annotations_parse_xml_file (xml_ascii_file, &list, FALSE); ++ if (list != NULL && !is_en) { ++ /* If emoji-test.txt has an emoji but $lang.xml does not, clear it ++ * since the language dicts do not want English annotations. ++ */ ++ NoTransData no_trans_data = { ++ xml_file, ++ xml_derived_file, ++ NULL ++ }; ++ g_slist_foreach (list, (GFunc)check_no_trans, &no_trans_data); ++ if (no_trans_data.emoji_list) { ++ g_slist_foreach (no_trans_data.emoji_list, ++ (GFunc)delete_emoji_from_list, ++ &list); ++ g_slist_free_full (no_trans_data.emoji_list, g_free); ++ } ++ } + if (list != NULL && output) + ibus_emoji_data_save (output, list); + if (list != NULL && output_category) +diff --git a/src/ibusemoji.c b/src/ibusemoji.c +index d2e16c5..3d38c2a 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 (4) ++#define IBUS_EMOJI_DATA_VERSION (5) + + enum { + PROP_0 = 0, +diff --git a/ui/gtk3/emojier.vala b/ui/gtk3/emojier.vala +index 1d105fd..95912bf 100644 +--- a/ui/gtk3/emojier.vala ++++ b/ui/gtk3/emojier.vala +@@ -190,9 +190,6 @@ class IBusEmojier : Gtk.ApplicationWindow { + private const string EMOJI_CATEGORY_OTHERS = N_("Others"); + private const unichar[] EMOJI_VARIANT_LIST = { + 0x1f3fb, 0x1f3fc, 0x1f3fd, 0x1f3fe, 0x1f3ff, 0x200d }; +- private const GLib.ActionEntry[] m_action_entries = { +- { "variant", check_action_variant_cb, null, "false", null } +- }; + + // Set the actual default values in the constructor + // because these fields are used for class_init() and static functions, +@@ -253,7 +250,13 @@ class IBusEmojier : Gtk.ApplicationWindow { + focus_visible : true + ); + +- add_action_entries(m_action_entries, this); ++ // GLib.ActionEntry accepts const variables only. ++ var action = new GLib.SimpleAction.stateful( ++ "variant", ++ null, ++ new GLib.Variant.boolean(m_show_emoji_variant)); ++ action.activate.connect(check_action_variant_cb); ++ add_action(action); + if (m_current_lang_id == null) + m_current_lang_id = "en"; + if (m_emoji_font_family == null) +@@ -521,18 +524,7 @@ class IBusEmojier : Gtk.ApplicationWindow { + m_emoji_to_data_dict.replace(emoji, data); + } else { + unowned IBus.EmojiData? en_data = null; +- // If emoji presentation (+= 0xfe0f) is already saved in dict, +- // update it instead of no presentation. +- // emoji-test.txt has all emoji presentations but $lang.xml has +- // some no emoji presentations. +- if (emoji.chr(-1, 0xfe0f) == null) { +- var buff = new GLib.StringBuilder(); +- buff.append(emoji); +- buff.append_unichar(0xfe0f); +- en_data = m_emoji_to_data_dict.lookup(buff.str); +- } +- if (en_data == null) +- en_data = m_emoji_to_data_dict.lookup(emoji); ++ en_data = m_emoji_to_data_dict.lookup(emoji); + if (en_data == null) { + m_emoji_to_data_dict.insert(emoji, data); + return; +@@ -923,7 +915,12 @@ class IBusEmojier : Gtk.ApplicationWindow { + m_vbox.add(button); + button.show_all(); + button.button_press_event.connect((w, e) => { +- hide_candidate_panel(); ++ // Bring back to emoji candidate panel in case ++ // m_show_emoji_variant is enabled and shows variants. ++ if (m_backward_index >= 0 && m_backward != null) ++ show_emoji_for_category(m_backward); ++ else ++ hide_candidate_panel(); + return true; + }); + } +@@ -1269,6 +1266,9 @@ class IBusEmojier : Gtk.ApplicationWindow { + GLib.Variant? parameter) { + m_show_emoji_variant = !action.get_state().get_boolean(); + action.set_state(new GLib.Variant.boolean(m_show_emoji_variant)); ++ // Redraw emoji candidate panel for m_show_emoji_variant ++ if (m_candidate_panel_is_visible) ++ show_candidate_panel(); + } + + +-- +2.9.3 + diff --git a/ibus.spec b/ibus.spec index 59abeff..4392281 100644 --- a/ibus.spec +++ b/ibus.spec @@ -28,7 +28,7 @@ Name: ibus Version: 1.5.16 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Intelligent Input Bus for Linux OS License: LGPLv2+ Group: System Environment/Libraries @@ -39,6 +39,7 @@ Source2: %{name}.conf.5 # Will remove the annotation tarball once the rpm is available on Fedora # Upstreamed patches. # Patch0: %%{name}-HEAD.patch +Patch0: %{name}-HEAD.patch BuildRequires: gettext-devel BuildRequires: libtool @@ -227,11 +228,13 @@ The ibus-devel-docs package contains developer documentation for IBus %setup -q # %%patch0 -p1 # cp client/gtk2/ibusimcontext.c client/gtk3/ibusimcontext.c || +%patch0 -p1 %build #autoreconf -f -i -v #make -C ui/gtk3 maintainer-clean-generic #make -C tools maintainer-clean-generic +autoreconf -f -i -v %configure \ --disable-static \ --enable-gtk2 \ @@ -250,6 +253,7 @@ The ibus-devel-docs package contains developer documentation for IBus --enable-introspection \ %{nil} +make -C ui/gtk3 maintainer-clean-generic make %{?_smp_mflags} %install @@ -416,6 +420,11 @@ gtk-query-immodules-3.0-%{__isa_bits} --update-cache &> /dev/null || : %{_datadir}/gtk-doc/html/* %changelog +* Mon May 29 2017 Takao Fujiwara - 1.5.16-2 +- Added ctrl-c,v,x for annotations and ctrl-shift-c for emoji +- Added Malay and Mongolian keymaps +- Made all emoji dicts to fully qualified + * Mon May 15 2017 Takao Fujiwara - 1.5.16-1 - Bumped to 1.5.16