public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
From: Takao Fujiwara <tfujiwar@redhat.com>
To: git-commits@fedoraproject.org
Subject: [rpms/ibus] autotool: Delete ibus-HEAD.patch
Date: Sun, 31 May 2026 02:06:39 GMT	[thread overview]
Message-ID: <178019319906.1.2017495390622560238.rpms-ibus-4950bbe7d42c@fedoraproject.org> (raw)

A new commit has been pushed.

Repo   : rpms/ibus
Branch : autotool
Commit : 4950bbe7d42cf6e36b52e9367cc176598b36750d
Author : Takao Fujiwara <tfujiwar@redhat.com>
Date   : 2017-10-22T20:16:24+09:00
Stats  : +0/-4358 in 1 file(s)
URL    : https://src.fedoraproject.org/rpms/ibus/c/4950bbe7d42cf6e36b52e9367cc176598b36750d?branch=autotool

Log:
Delete ibus-HEAD.patch

---
diff --git a/ibus-HEAD.patch b/ibus-HEAD.patch
deleted file mode 100644
index 65b7db7..0000000
--- a/ibus-HEAD.patch
+++ /dev/null
@@ -1,4358 +0,0 @@
-From e6bab7ab78c69d238a70a64e60963dd5a6711ffe Mon Sep 17 00:00:00 2001
-From: Felix Yan <felixonmars@archlinux.org>
-Date: Fri, 19 May 2017 12:13:04 +0900
-Subject: [PATCH] Fix a typo in configure.ac
-
-BUG=https://github.com/ibus/ibus/pull/1927
-R=Shawn.P.Huang@gmail.com
-
-Review URL: https://codereview.appspot.com/317640043
-
-Patch from Felix Yan <felixonmars@archlinux.org>.
----
- configure.ac | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/configure.ac b/configure.ac
-index 219b89d..2cc96d1 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -727,7 +727,7 @@ Build options:
-   Enable surrounding-text       $enable_surrounding_text
-   Enable libnotify              $enable_libnotify
-   Enable Emoji dict             $enable_emoji_dict
--  Uicode Emoji directory        $UNICODE_EMOJI_DIR
-+  Unicode Emoji directory       $UNICODE_EMOJI_DIR
-   CLDR annotation directory     $EMOJI_ANNOTATION_DIR
-   Run test cases                $enable_tests
- ])
--- 
-2.9.3
-
-From 4fe3050efa7335f82870fb1d5a1d170d20afc160 Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-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 <takao.fujiwara1@gmail.com>
-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 @@
-                         <icon>ibus-keyboard</icon>
- 			<rank>1</rank>
- 		</engine>
-+                <engine>
-+                        <name>xkb:my::msa</name>
-+                        <language>ms</language>
-+                        <license>GPL</license>
-+                        <author>Peng Huang &lt;shawn.p.huang@gmail.com&gt;</author>
-+                        <layout>my</layout>
-+                        <longname>Malay (Jawi)</longname>
-+                        <description>Malay (Jawi)</description>
-+                        <icon>ibus-keyboard</icon>
-+                        <rank>1</rank>
-+                </engine>
-+                <engine>
-+                        <name>xkb:mn::mon</name>
-+                        <language>mn</language>
-+                        <license>GPL</license>
-+                        <author>Peng Huang &lt;shawn.p.huang@gmail.com&gt;</author>
-+                        <layout>mn</layout>
-+                        <longname>Mongolian</longname>
-+                        <description>Mongolian</description>
-+                        <icon>ibus-keyboard</icon>
-+                        <rank>1</rank>
-+                </engine>
- 	</engines>
- </component>
--- 
-2.9.3
-
-From 081d09f1a927f459dacda3bcc59a1678ca2f9a95 Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-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 <takao.fujiwara1@gmail.com>
-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 <config.h>
-+#endif
-+
- #include <glib.h>
- 
- #ifdef HAVE_JSON_GLIB1
- #include <json-glib/json-glib.h>
- #endif
- 
-+#ifdef HAVE_LOCALE_H
-+#include <locale.h>
-+#endif
-+
- #include <string.h>
- 
- #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
-
-From bc0f91342c6f3a6e554493af9430d634d906ee19 Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Tue, 25 Jul 2017 12:00:14 +0900
-Subject: [PATCH] ui/gtk3: Fix SEGV of IBusEmojier on de_DE.UTF-8
-
-de's decimal_point is ',' instead of '.' and failed to load the
-CSS data in Gtk.CssProvider.load_from_data(), launched null
-window of emojis and finally caused a SEGV due to the null window.
-This also fixes some memory leaks.
-
-BUG=rhbz#1471079
-
-Review URL: https://codereview.appspot.com/323310043
----
- src/ibusemoji.c      |  1 +
- ui/gtk3/emojier.vala | 33 ++++++++++++++++++++++++++-------
- 2 files changed, 27 insertions(+), 7 deletions(-)
-
-diff --git a/src/ibusemoji.c b/src/ibusemoji.c
-index 3d38c2a..d56c48a 100644
---- a/src/ibusemoji.c
-+++ b/src/ibusemoji.c
-@@ -591,6 +591,7 @@ out_load_cache:
-         g_variant_unref (variant);
-     if (variant_table)
-         g_variant_unref (variant_table);
-+    g_free (contents);
- 
-     return retval;
- }
-diff --git a/ui/gtk3/emojier.vala b/ui/gtk3/emojier.vala
-index 95912bf..9df59ac 100644
---- a/ui/gtk3/emojier.vala
-+++ b/ui/gtk3/emojier.vala
-@@ -276,6 +276,17 @@ class IBusEmojier : Gtk.ApplicationWindow {
-             warning("Could not open display.");
-             return;
-         }
-+        // Set en locale because de_DE's decimal_point is ',' instead of '.'
-+        string? backup_locale =
-+            Intl.setlocale(LocaleCategory.NUMERIC, null).dup();
-+        if (Intl.setlocale(LocaleCategory.NUMERIC, "en_US.UTF-8") == null) {
-+          if (Intl.setlocale(LocaleCategory.NUMERIC, "C.UTF-8") == null) {
-+              if (Intl.setlocale(LocaleCategory.NUMERIC, "C") == null) {
-+                  warning("You don't install either en_US.UTF-8 or C.UTF-8 " +
-+                          "or C locale");
-+              }
-+          }
-+        }
-         m_rgba = new ThemedRGBA(this);
-         uint bg_red = (uint)(m_rgba.normal_bg.red * 255);
-         uint bg_green = (uint)(m_rgba.normal_bg.green * 255);
-@@ -321,6 +332,10 @@ class IBusEmojier : Gtk.ApplicationWindow {
-             warning("Failed css_provider_from_data: %s", e.message);
-             return;
-         }
-+        if (backup_locale != null)
-+            Intl.setlocale(LocaleCategory.NUMERIC, backup_locale);
-+        else
-+            Intl.setlocale(LocaleCategory.NUMERIC, "");
- 
-         Gtk.StyleContext.add_provider_for_screen(
-                 screen,
-@@ -424,8 +439,9 @@ class IBusEmojier : Gtk.ApplicationWindow {
-         unowned GLib.SList<string> annotations = data.get_annotations();
-         foreach (string annotation in annotations) {
-             bool has_emoji = false;
--            unowned GLib.SList<string> hits =
--                    m_annotation_to_emojis_dict.lookup(annotation);
-+            GLib.SList<string> hits =
-+                    m_annotation_to_emojis_dict.lookup(annotation).copy_deep(
-+                            GLib.strdup);
-             foreach (string hit_emoji in hits) {
-                 if (hit_emoji == emoji) {
-                     has_emoji = true;
-@@ -485,7 +501,8 @@ class IBusEmojier : Gtk.ApplicationWindow {
-     private static void
-     update_annotations_with_description (IBus.EmojiData data,
-                                          string         description) {
--        unowned GLib.SList<string> annotations = data.get_annotations();
-+        GLib.SList<string> annotations =
-+                data.get_annotations().copy_deep(GLib.strdup);
-         bool update_annotations = false;
-         string former = null;
-         string later = null;
-@@ -574,8 +591,9 @@ class IBusEmojier : Gtk.ApplicationWindow {
-                 buff.append_unichar(0xfe0f);
-                 if (m_emoji_to_data_dict.lookup(buff.str) != null)
-                     base_emoji = buff.str;
--                unowned GLib.SList<string>? variants =
--                    m_emoji_to_emoji_variants_dict.lookup(base_emoji);
-+                GLib.SList<string>? variants =
-+                        m_emoji_to_emoji_variants_dict.lookup(
-+                                base_emoji).copy_deep(GLib.strdup);
-                 if (variants.find_custom(emoji, GLib.strcmp) == null) {
-                     if (variants == null)
-                         variants.append(base_emoji);
-@@ -587,8 +605,9 @@ class IBusEmojier : Gtk.ApplicationWindow {
-                 return;
-             }
-             bool has_emoji = false;
--            unowned GLib.SList<string> hits =
--                    m_category_to_emojis_dict.lookup(category);
-+            GLib.SList<string> hits =
-+                    m_category_to_emojis_dict.lookup(category).copy_deep(
-+                            GLib.strdup);
-             foreach (string hit_emoji in hits) {
-                 if (hit_emoji == emoji) {
-                     has_emoji = true;
--- 
-2.9.3
-
-From 4134113a1ae30534367a9ca729c7f36a0a8e3662 Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Thu, 27 Jul 2017 14:07:00 +0900
-Subject: [PATCH] ui/gtk3: Fix SEGV of XKeysymToKeycode() on Wayland
-
-BUG=rhbz#1368593
----
- ui/gtk3/application.vala | 4 ++++
- 1 file changed, 4 insertions(+)
-
-diff --git a/ui/gtk3/application.vala b/ui/gtk3/application.vala
-index 5ae6e83..fa80272 100644
---- a/ui/gtk3/application.vala
-+++ b/ui/gtk3/application.vala
-@@ -3,6 +3,7 @@
-  * ibus - The Input Bus
-  *
-  * Copyright(c) 2011 Peng Huang <shawn.p.huang@gmail.com>
-+ * Copyright(c) 2017 Takao Fujiwara <takao.fujiwara1@gmail.com>
-  *
-  * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Lesser General Public
-@@ -99,6 +100,9 @@ class Application {
-     }
- 
-     public static void main(string[] argv) {
-+        // for Gdk.X11.get_default_xdisplay()
-+        Gdk.set_allowed_backends("x11");
-+
-         Application app = new Application(argv);
-         app.run();
-     }
--- 
-2.9.3
-
-From 6a3301db85e77e0652f7e00894cce493b6a942f6 Mon Sep 17 00:00:00 2001
-From: Xiang Fan <sfanxiang@gmail.com>
-Date: Thu, 10 Aug 2017 11:24:39 +0900
-Subject: [PATCH 01/14] client/gtk2: include the scaling factor
-
-Scaling factor, which exists for HiDPI displays, needs to be included in
-the calculation of cursor location. This does not affect devices without
-a HiDPI display.
-
-Candidate windows would be misplaced to smaller coordinates without this
-patch.
-
-BUG=https://github.com/ibus/ibus/issues/1806
-
-Review URL: https://codereview.appspot.com/328250043
-
-Patch from Xiang Fan <sfanxiang@gmail.com>.
----
- client/gtk2/ibusimcontext.c | 21 +++++++++++++++++++++
- 1 file changed, 21 insertions(+)
-
-diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c
-index 0df00620..41c7a3af 100644
---- a/client/gtk2/ibusimcontext.c
-+++ b/client/gtk2/ibusimcontext.c
-@@ -999,6 +999,24 @@ ibus_im_context_set_client_window (GtkIMContext *context, GdkWindow *client)
-         gtk_im_context_set_client_window (ibusimcontext->slave, client);
- }
- 
-+static void
-+_set_rect_scale_factor_with_window (GdkRectangle *area,
-+                                    GdkWindow    *window)
-+{
-+#if GTK_CHECK_VERSION (3, 10, 0)
-+    int scale_factor;
-+
-+    g_assert (area);
-+    g_assert (GDK_IS_WINDOW (window));
-+
-+    scale_factor = gdk_window_get_scale_factor (window);
-+    area->x *= scale_factor;
-+    area->y *= scale_factor;
-+    area->width *= scale_factor;
-+    area->height *= scale_factor;
-+#endif
-+}
-+
- static gboolean
- _set_cursor_location_internal (IBusIMContext *ibusimcontext)
- {
-@@ -1024,6 +1042,8 @@ _set_cursor_location_internal (IBusIMContext *ibusimcontext)
-             window = parent;
-         }
- 
-+        _set_rect_scale_factor_with_window (&area,
-+                                            ibusimcontext->client_window);
-         ibus_input_context_set_cursor_location_relative (
-             ibusimcontext->ibuscontext,
-             area.x,
-@@ -1049,6 +1069,7 @@ _set_cursor_location_internal (IBusIMContext *ibusimcontext)
-     gdk_window_get_root_coords (ibusimcontext->client_window,
-                                 area.x, area.y,
-                                 &area.x, &area.y);
-+    _set_rect_scale_factor_with_window (&area, ibusimcontext->client_window);
-     ibus_input_context_set_cursor_location (ibusimcontext->ibuscontext,
-                                             area.x,
-                                             area.y,
--- 
-2.13.4
-
-From c1b93f933f5cbd74f3e06575d26ed7432a5420fd Mon Sep 17 00:00:00 2001
-From: Mario Bodemann <mario.bodemann@gmail.com>
-Date: Tue, 15 Aug 2017 12:10:56 +0900
-Subject: [PATCH 02/14] Typo fix
-
-BUG=https://github.com/ibus/ibus/pull/1939
-
-Review URL: https://codereview.appspot.com/327080043
-
-Patch from Mario Bodemann <mario.bodemann@gmail.com>.
----
- ui/gtk3/ibus-emoji.7.in | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/ui/gtk3/ibus-emoji.7.in b/ui/gtk3/ibus-emoji.7.in
-index 4ee86364..d5eae310 100644
---- a/ui/gtk3/ibus-emoji.7.in
-+++ b/ui/gtk3/ibus-emoji.7.in
-@@ -15,7 +15,7 @@
- .SH "DESCRIPTION"
- 
- .PP
--IBus Emojier provides a GUI to select an emoji by typing an emoji annotaion
-+IBus Emojier provides a GUI to select an emoji by typing an emoji annotation
- or choosing a character with mouse click and it's designed to work as
- an extended IBus lookup window using Space, Enter, and Arrow keys.
- The text entry accepts an emoji annotation or Unicode points.
--- 
-2.13.4
-
-From 203a3df5a239d644cf42b7bac03a268eb5babfc7 Mon Sep 17 00:00:00 2001
-From: Alexander Larsson <alexl@redhat.com>
-Date: Wed, 30 Aug 2017 11:38:09 +0900
-Subject: [PATCH 03/14] Initial version of ibus portal
-
-This adds a dbus service called org.freedesktop.portal.IBus on the
-session bus. It is a very limited service that only implements
-CreateInputContext and the InputContext interface (and Service.Destroy
-for lifetime access).
-
-It uses gdbus code generation for demarshalling the method calls which
-means it will verify that all arguments have the right type.
-
-Additionally all method calls to the input context object have to be
-from the client that created it, so each client is isolated.
-
-BUG=https://github.com/flatpak/flatpak/issues/675
-R=Shawn.P.Huang@gmail.com
-
-Review URL: https://codereview.appspot.com/326350043
-
-Patch from Alexander Larsson <alexl@redhat.com>.
----
- Makefile.am                                   |   1 +
- configure.ac                                  |   5 +-
- portal/Makefile.am                            |  95 ++++
- portal/org.freedesktop.IBus.Portal.xml        | 132 +++++
- portal/org.freedesktop.portal.IBus.service.in |   3 +
- portal/portal.c                               | 698 ++++++++++++++++++++++++++
- src/ibusshare.h                               |  14 +
- 7 files changed, 947 insertions(+), 1 deletion(-)
- create mode 100644 portal/Makefile.am
- create mode 100644 portal/org.freedesktop.IBus.Portal.xml
- create mode 100644 portal/org.freedesktop.portal.IBus.service.in
- create mode 100644 portal/portal.c
-
-diff --git a/Makefile.am b/Makefile.am
-index f703d4c6..c8e802da 100644
---- a/Makefile.am
-+++ b/Makefile.am
-@@ -51,6 +51,7 @@ SUBDIRS = \
- 	util \
- 	conf \
- 	client \
-+	portal \
- 	data \
- 	m4 \
- 	po \
-diff --git a/configure.ac b/configure.ac
-index cb48ad4c..14556a3a 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -153,7 +153,7 @@ PKG_CHECK_MODULES(GOBJECT2, [
-     gobject-2.0 >= glib_required_version
- ])
- PKG_CHECK_MODULES(GIO2, [
--    gio-2.0 >= glib_required_version
-+    gio-2.0 gio-unix-2.0 >= glib_required_version
- ])
- PKG_CHECK_MODULES(GTHREAD2, [
-     gthread-2.0 >= glib_required_version
-@@ -660,6 +660,8 @@ PKG_CHECK_MODULES(ISOCODES, [
- ISOCODES_PREFIX=`$PKG_CONFIG iso-codes --variable=prefix`
- AC_SUBST(ISOCODES_PREFIX)
- 
-+AC_SUBST([GDBUS_CODEGEN], [`$PKG_CONFIG --variable gdbus_codegen gio-2.0`])
-+
- # OUTPUT files
- AC_CONFIG_FILES([ po/Makefile.in
- Makefile
-@@ -674,6 +676,7 @@ src/Makefile
- src/ibusversion.h
- src/tests/Makefile
- bus/Makefile
-+portal/Makefile
- engine/Makefile
- util/Makefile
- util/IMdkit/Makefile
-diff --git a/portal/Makefile.am b/portal/Makefile.am
-new file mode 100644
-index 00000000..954fc591
---- /dev/null
-+++ b/portal/Makefile.am
-@@ -0,0 +1,95 @@
-+# vim:set noet ts=4:
-+#
-+# ibus - The Input Bus
-+#
-+# Copyright (c) 2007-2013 Peng Huang <shawn.p.huang@gmail.com>
-+# Copyright (c) 2007-2013 Red Hat, Inc.
-+#
-+# This library is free software; you can redistribute it and/or
-+# modify it under the terms of the GNU Lesser General Public
-+# License as published by the Free Software Foundation; either
-+# version 2.1 of the License, or (at your option) any later version.
-+#
-+# This library is distributed in the hope that it will be useful,
-+# but WITHOUT ANY WARRANTY; without even the implied warranty of
-+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+# Lesser General Public License for more details.
-+#
-+# You should have received a copy of the GNU Lesser General Public
-+# License along with this library; if not, write to the Free Software
-+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
-+# USA
-+
-+NULL =
-+
-+libibus = $(top_builddir)/src/libibus-@IBUS_API_VERSION@.la
-+
-+AM_CPPFLAGS = \
-+	-I$(top_srcdir)/src   \
-+	-I$(top_builddir)/src \
-+	$(NULL)
-+
-+AM_CFLAGS = \
-+	@GLIB2_CFLAGS@ \
-+	@GIO2_CFLAGS@ \
-+	@GTHREAD2_CFLAGS@ \
-+	-DG_LOG_DOMAIN=\"IBUS\" \
-+	-DPKGDATADIR=\"$(pkgdatadir)\" \
-+	-DLIBEXECDIR=\"$(libexecdir)\" \
-+	-DBINDIR=\"@bindir@\" \
-+	-DIBUS_DISABLE_DEPRECATED \
-+	$(NULL)
-+AM_LDADD = \
-+	@GOBJECT2_LIBS@ \
-+	@GLIB2_LIBS@ \
-+	@GIO2_LIBS@ \
-+	@GTHREAD2_LIBS@ \
-+	$(libibus) \
-+	$(NULL)
-+
-+ibus_dbus_built_sources = ibus-portal-dbus.c ibus-portal-dbus.h
-+BUILT_SOURCES = $(ibus_dbus_built_sources)
-+
-+libexec_PROGRAMS = ibus-portal
-+ibus_portal_DEPENDENCIES = \
-+	$(libibus) \
-+	$(NULL)
-+ibus_portal_SOURCES = \
-+	portal.c \
-+	$(ibus_dbus_built_sources) \
-+	$(NULL)
-+ibus_portal_CFLAGS = \
-+	$(AM_CFLAGS) \
-+	$(NULL)
-+ibus_portal_LDADD = \
-+	$(AM_LDADD) \
-+	$(NULL)
-+
-+EXTRA_DIST = \
-+	$(NULL)
-+
-+CLEANFILES = \
-+	$(NULL)
-+
-+$(libibus):
-+	$(MAKE) -C $(top_builddir)/src
-+
-+dbusservice_in_files = org.freedesktop.portal.IBus.service.in
-+dbusservice_DATA = $(dbusservice_in_files:.service.in=.service)
-+dbusservicedir=${datadir}/dbus-1/services
-+
-+org.freedesktop.portal.IBus.service: org.freedesktop.portal.IBus.service.in
-+	$(AM_V_GEN) sed -e "s|\@libexecdir\@|$(libexecdir)|"  $< > $@.tmp && mv $@.tmp $@
-+
-+$(ibus_dbus_built_sources) : org.freedesktop.IBus.Portal.xml
-+	$(AM_V_GEN) $(GDBUS_CODEGEN)                            \
-+		--interface-prefix org.freedesktop.IBus.        \
-+		--c-namespace IBusDbus                          \
-+		--generate-c-code $(builddir)/ibus-portal-dbus  \
-+		$^ \
-+		$(NULL)
-+
-+EXTRA_DIST += $(dbusservice_in_files)
-+CLEANFILES += $(dbusservice_DATA)
-+
-+-include $(top_srcdir)/git.mk
-diff --git a/portal/org.freedesktop.IBus.Portal.xml b/portal/org.freedesktop.IBus.Portal.xml
-new file mode 100644
-index 00000000..afce4daa
---- /dev/null
-+++ b/portal/org.freedesktop.IBus.Portal.xml
-@@ -0,0 +1,132 @@
-+<?xml version="1.0"?>
-+<!--
-+ Copyright (C) 2017 Red Hat, Inc.
-+
-+ This library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2 of the License, or (at your option) any later version.
-+
-+ This library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with this library. If not, see <http://www.gnu.org/licenses/>.
-+
-+ Author: Alexander Larsson <alexl@redhat.com>
-+-->
-+
-+<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
-+  <!--
-+      org.freedesktop.IBus.Portal:
-+      @short_description: Portal for ibus client access
-+
-+      This interface is a minimal interface to IBus that is safe to expose to
-+      clients.
-+  -->
-+  <interface name="org.freedesktop.IBus.Portal">
-+    <method name='CreateInputContext'>
-+      <arg direction='in'  type='s' name='client_name' />
-+      <arg direction='out' type='o' name='object_path' />
-+    </method>
-+  </interface>
-+
-+  <!-- This is a copy of the interface in inputcontext.c, they should be shared.
-+       We want this for the code generator so that we can be sure we verify all
-+       caller types, etc.
-+  -->
-+  <interface name='org.freedesktop.IBus.InputContext'>
-+    <method name='ProcessKeyEvent'>
-+      <arg direction='in'  type='u' name='keyval' />
-+      <arg direction='in'  type='u' name='keycode' />
-+      <arg direction='in'  type='u' name='state' />
-+      <arg direction='out' type='b' name='handled' />
-+    </method>
-+    <method name='SetCursorLocation'>
-+      <arg direction='in' type='i' name='x' />
-+      <arg direction='in' type='i' name='y' />
-+      <arg direction='in' type='i' name='w' />
-+      <arg direction='in' type='i' name='h' />
-+    </method>
-+    <method name='SetCursorLocationRelative'>
-+      <arg direction='in' type='i' name='x' />
-+      <arg direction='in' type='i' name='y' />
-+      <arg direction='in' type='i' name='w' />
-+      <arg direction='in' type='i' name='h' />
-+    </method>
-+    <method name='ProcessHandWritingEvent'>
-+      <arg direction='in' type='ad' name='coordinates' />
-+    </method>
-+    <method name='CancelHandWriting'>
-+      <arg direction='in' type='u' name='n_strokes' />
-+    </method>
-+    <method name='FocusIn' />
-+    <method name='FocusOut' />
-+    <method name='Reset' />
-+    <method name='SetCapabilities'>
-+      <arg direction='in' type='u' name='caps' />
-+    </method>
-+    <method name='PropertyActivate'>
-+      <arg direction='in' type='s' name='name' />
-+      <arg direction='in' type='u' name='state' />
-+    </method>
-+    <method name='SetEngine'>
-+      <arg direction='in' type='s' name='name' />
-+    </method>
-+    <method name='GetEngine'>
-+      <arg direction='out' type='v' name='desc' />
-+    </method>
-+    <method name='SetSurroundingText'>
-+      <arg direction='in' type='v' name='text' />
-+      <arg direction='in' type='u' name='cursor_pos' />
-+      <arg direction='in' type='u' name='anchor_pos' />
-+    </method>
-+
-+    <signal name='CommitText'>
-+      <arg type='v' name='text' />
-+    </signal>
-+    <signal name='ForwardKeyEvent'>
-+      <arg type='u' name='keyval' />
-+      <arg type='u' name='keycode' />
-+      <arg type='u' name='state' />
-+    </signal>
-+    <signal name='UpdatePreeditText'>
-+      <arg type='v' name='text' />
-+      <arg type='u' name='cursor_pos' />
-+      <arg type='b' name='visible' />
-+    </signal>
-+    <signal name='ShowPreeditText'/>
-+    <signal name='HidePreeditText'/>
-+    <signal name='UpdateAuxiliaryText'>
-+      <arg type='v' name='text' />
-+      <arg type='b' name='visible' />
-+    </signal>
-+    <signal name='ShowAuxiliaryText'/>
-+    <signal name='HideAuxiliaryText'/>
-+    <signal name='UpdateLookupTable'>
-+      <arg type='v' name='table' />
-+      <arg type='b' name='visible' />
-+    </signal>
-+    <signal name='ShowLookupTable'/>
-+    <signal name='HideLookupTable'/>
-+    <signal name='PageUpLookupTable'/>
-+    <signal name='PageDownLookupTable'/>
-+    <signal name='CursorUpLookupTable'/>
-+    <signal name='CursorDownLookupTable'/>
-+    <signal name='RegisterProperties'>
-+      <arg type='v' name='props' />
-+    </signal>
-+    <signal name='UpdateProperty'>
-+      <arg type='v' name='prop' />
-+    </signal>
-+
-+    <property name='ContentType' type='(uu)' access='write' />
-+  </interface>
-+
-+  <interface name='org.freedesktop.IBus.Service'>
-+    <method name='Destroy' />
-+  </interface>
-+
-+</node>
-diff --git a/portal/org.freedesktop.portal.IBus.service.in b/portal/org.freedesktop.portal.IBus.service.in
-new file mode 100644
-index 00000000..47ae9ffc
---- /dev/null
-+++ b/portal/org.freedesktop.portal.IBus.service.in
-@@ -0,0 +1,3 @@
-+[D-BUS Service]
-+Name=org.freedesktop.portal.IBus
-+Exec=@libexecdir@/ibus-portal
-diff --git a/portal/portal.c b/portal/portal.c
-new file mode 100644
-index 00000000..0415f996
---- /dev/null
-+++ b/portal/portal.c
-@@ -0,0 +1,698 @@
-+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
-+/* vim:set et sts=4: */
-+/* ibus - The Input Bus
-+ * Copyright (C) 2017 Red Hat, Inc.
-+ *
-+ * This library is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU Lesser General Public
-+ * License as published by the Free Software Foundation; either
-+ * version 2.1 of the License, or (at your option) any later version.
-+ *
-+ * This library is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+ * Lesser General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU Lesser General Public
-+ * License along with this library; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
-+ * USA
-+ */
-+#include <config.h>
-+#include <fcntl.h>
-+#include <glib.h>
-+#include <gio/gio.h>
-+#include <ibus.h>
-+#include <locale.h>
-+#include <pwd.h>
-+#include <signal.h>
-+#include <stdlib.h>
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+#include <unistd.h>
-+
-+#include "ibus-portal-dbus.h"
-+
-+typedef struct _IBusPortal IBusPortal;
-+typedef struct _IBusPortalClass IBusPortalClass;
-+typedef struct _IBusPortalContext IBusPortalContext;
-+typedef struct _IBusPortalContextClass IBusPortalContextClass;
-+
-+struct _IBusPortalContext
-+{
-+    IBusDbusInputContextSkeleton parent_instance;
-+    IBusInputContext *context;
-+    guint id;
-+    char *owner;
-+    char *object_path;
-+    IBusDbusService *service;
-+};
-+
-+struct _IBusPortalContextClass
-+{
-+    IBusDbusInputContextSkeletonClass parent_class;
-+};
-+
-+struct _IBusPortal
-+{
-+    IBusDbusPortalSkeleton parent_instance;
-+
-+};
-+
-+struct _IBusPortalClass
-+{
-+    IBusDbusPortalSkeletonClass parent_class;
-+};
-+
-+enum
-+{
-+    PROP_CONTENT_TYPE = 1,
-+    N_PROPERTIES
-+};
-+
-+static GMainLoop *loop = NULL;
-+static IBusBus *ibus_bus;
-+static IBusPortal *ibus_portal = NULL;
-+static gboolean opt_verbose;
-+static gboolean opt_replace;
-+
-+static GList *all_contexts = NULL;
-+
-+static guint next_context_id;
-+
-+GType ibus_portal_context_get_type (void) G_GNUC_CONST;
-+static void ibus_portal_context_iface_init (IBusDbusInputContextIface *iface);
-+
-+static void portal_context_g_signal (GDBusProxy        *proxy,
-+                                     const gchar       *sender_name,
-+                                     const gchar       *signal_name,
-+                                     GVariant          *parameters,
-+                                     IBusPortalContext *portal_context);
-+
-+G_DEFINE_TYPE_WITH_CODE (IBusPortalContext,
-+                         ibus_portal_context,
-+                         IBUS_DBUS_TYPE_INPUT_CONTEXT_SKELETON,
-+                         G_IMPLEMENT_INTERFACE (IBUS_DBUS_TYPE_INPUT_CONTEXT,
-+                                 ibus_portal_context_iface_init));
-+
-+static void
-+_forward_method_cb (GObject *source_object,
-+                    GAsyncResult *res,
-+                    gpointer user_data)
-+{
-+    GDBusMethodInvocation *invocation = user_data;
-+    IBusPortalContext *portal_context =
-+            (IBusPortalContext *) g_dbus_method_invocation_get_user_data (
-+                    invocation);
-+    IBusEngineDesc *desc;
-+    GError *error = NULL;
-+
-+    GVariant *variant = g_dbus_proxy_call_finish ((GDBusProxy *) source_object,
-+                                                  res, &error);
-+    if (variant == NULL) {
-+        g_dbus_method_invocation_return_gerror (invocation, error);
-+        g_error_free (error);
-+        return;
-+    }
-+
-+    g_dbus_method_invocation_return_value (invocation, variant);
-+}
-+
-+static gboolean
-+_forward_method (IBusDbusInputContext  *object,
-+                 GDBusMethodInvocation *invocation)
-+{
-+    IBusPortalContext *portal_context = (IBusPortalContext *)object;
-+    GDBusMessage *message = g_dbus_method_invocation_get_message (invocation);
-+
-+    g_dbus_proxy_call (G_DBUS_PROXY (portal_context->context),
-+                       g_dbus_method_invocation_get_method_name (invocation),
-+                       g_dbus_message_get_body (message),
-+                       G_DBUS_CALL_FLAGS_NONE,
-+                       -1,
-+                       NULL, /* cancellable */
-+                       _forward_method_cb, invocation);
-+    return TRUE;
-+}
-+
-+static gboolean
-+ibus_dbus_context_cancel_hand_writing (IBusDbusInputContext  *object,
-+                                       GDBusMethodInvocation *invocation,
-+                                       guint                  arg_n_strokes)
-+{
-+    return _forward_method (object, invocation);
-+}
-+
-+static gboolean
-+ibus_dbus_context_focus_in (IBusDbusInputContext  *object,
-+                            GDBusMethodInvocation *invocation)
-+{
-+    return _forward_method (object, invocation);
-+}
-+
-+static gboolean
-+ibus_dbus_context_focus_out (IBusDbusInputContext  *object,
-+                             GDBusMethodInvocation *invocation)
-+{
-+    return _forward_method (object, invocation);
-+}
-+
-+static gboolean
-+ibus_dbus_context_get_engine (IBusDbusInputContext  *object,
-+                              GDBusMethodInvocation *invocation)
-+{
-+    return _forward_method (object, invocation);
-+}
-+
-+static gboolean
-+ibus_dbus_context_process_hand_writing_event (IBusDbusInputContext  *object,
-+                                              GDBusMethodInvocation *invocation,
-+                                              GVariant
-+                                                               *arg_coordinates)
-+{
-+    return _forward_method (object, invocation);
-+}
-+
-+static gboolean
-+ibus_dbus_context_process_key_event (IBusDbusInputContext  *object,
-+                                     GDBusMethodInvocation *invocation,
-+                                     guint                  arg_keyval,
-+                                     guint                  arg_keycode,
-+                                     guint                  arg_state)
-+{
-+    return _forward_method (object, invocation);
-+}
-+
-+static gboolean
-+ibus_dbus_context_property_activate (IBusDbusInputContext  *object,
-+                                     GDBusMethodInvocation *invocation,
-+                                     const gchar           *arg_name,
-+                                     guint                  arg_state)
-+{
-+    return _forward_method (object, invocation);
-+}
-+
-+static gboolean
-+ibus_dbus_context_reset (IBusDbusInputContext  *object,
-+                         GDBusMethodInvocation *invocation)
-+{
-+    return _forward_method (object, invocation);
-+}
-+
-+static gboolean
-+ibus_dbus_context_set_capabilities (IBusDbusInputContext  *object,
-+                                    GDBusMethodInvocation *invocation,
-+                                    guint                  arg_caps)
-+{
-+    return _forward_method (object, invocation);
-+}
-+
-+static gboolean
-+ibus_dbus_context_set_cursor_location (IBusDbusInputContext  *object,
-+                                       GDBusMethodInvocation *invocation,
-+                                       gint                   arg_x,
-+                                       gint                   arg_y,
-+                                       gint                   arg_w,
-+                                       gint                   arg_h)
-+{
-+    return _forward_method (object, invocation);
-+}
-+
-+static gboolean
-+ibus_dbus_context_set_cursor_location_relative (IBusDbusInputContext  *object,
-+                                                GDBusMethodInvocation
-+                                                                    *invocation,
-+                                                gint                   arg_x,
-+                                                gint                   arg_y,
-+                                                gint                   arg_w,
-+                                                gint                   arg_h)
-+{
-+    return _forward_method (object, invocation);
-+}
-+
-+static gboolean
-+ibus_dbus_context_set_engine (IBusDbusInputContext  *object,
-+                              GDBusMethodInvocation *invocation,
-+                              const gchar           *arg_name)
-+{
-+    return _forward_method (object, invocation);
-+}
-+
-+static gboolean
-+ibus_dbus_context_set_surrounding_text (IBusDbusInputContext  *object,
-+                                        GDBusMethodInvocation *invocation,
-+                                        GVariant              *arg_text,
-+                                        guint                  arg_cursor_pos,
-+                                        guint                  arg_anchor_pos)
-+{
-+    return _forward_method (object, invocation);
-+}
-+
-+static void
-+ibus_portal_context_iface_init (IBusDbusInputContextIface *iface)
-+{
-+    iface->handle_cancel_hand_writing = ibus_dbus_context_cancel_hand_writing;
-+    iface->handle_focus_in = ibus_dbus_context_focus_in;
-+    iface->handle_focus_out = ibus_dbus_context_focus_out;
-+    iface->handle_get_engine = ibus_dbus_context_get_engine;
-+    iface->handle_process_hand_writing_event =
-+            ibus_dbus_context_process_hand_writing_event;
-+    iface->handle_process_key_event = ibus_dbus_context_process_key_event;
-+    iface->handle_property_activate = ibus_dbus_context_property_activate;
-+    iface->handle_reset = ibus_dbus_context_reset;
-+    iface->handle_set_capabilities = ibus_dbus_context_set_capabilities;
-+    iface->handle_set_cursor_location = ibus_dbus_context_set_cursor_location;
-+    iface->handle_set_cursor_location_relative =
-+            ibus_dbus_context_set_cursor_location_relative;
-+    iface->handle_set_engine = ibus_dbus_context_set_engine;
-+    iface->handle_set_surrounding_text = ibus_dbus_context_set_surrounding_text;
-+}
-+
-+static void
-+ibus_portal_context_init (IBusPortalContext *portal_context)
-+{
-+}
-+
-+static void
-+ibus_portal_context_finalize (GObject *object)
-+{
-+    IBusPortalContext *portal_context = (IBusPortalContext *)object;
-+
-+    all_contexts = g_list_remove (all_contexts, portal_context);
-+
-+    g_dbus_interface_skeleton_unexport (
-+            G_DBUS_INTERFACE_SKELETON (portal_context->service));
-+    g_dbus_interface_skeleton_unexport (
-+            G_DBUS_INTERFACE_SKELETON (portal_context));
-+
-+    g_free (portal_context->owner);
-+    g_free (portal_context->object_path);
-+    g_object_unref (portal_context->service);
-+
-+    g_signal_handlers_disconnect_by_func (
-+            portal_context->context,
-+            G_CALLBACK(portal_context_g_signal),
-+            portal_context);
-+    g_object_unref (portal_context->context);
-+
-+    G_OBJECT_CLASS (ibus_portal_context_parent_class)->finalize (object);
-+}
-+
-+static void
-+ibus_portal_context_set_property (IBusPortalContext *portal_context,
-+                                  guint              prop_id,
-+                                  const GValue      *value,
-+                                  GParamSpec        *pspec)
-+{
-+    switch (prop_id) {
-+    case PROP_CONTENT_TYPE:
-+        g_dbus_proxy_call (G_DBUS_PROXY (portal_context->context),
-+                           "org.freedesktop.DBus.Properties.Set",
-+                           g_variant_new ("(ssv)",
-+                                          IBUS_INTERFACE_INPUT_CONTEXT,
-+                                          "ContentType",
-+                                          g_value_get_variant (value)),
-+                           G_DBUS_CALL_FLAGS_NONE,
-+                           -1,
-+                           NULL, /* cancellable */
-+                           NULL, /* callback */
-+                           NULL  /* user_data */
-+                           );
-+        break;
-+    default:
-+        G_OBJECT_WARN_INVALID_PROPERTY_ID (portal_context, prop_id, pspec);
-+    }
-+}
-+
-+static void
-+ibus_portal_context_get_property (IBusPortalContext *portal_context,
-+                                  guint              prop_id,
-+                                  GValue            *value,
-+                                  GParamSpec        *pspec)
-+{
-+    switch (prop_id) {
-+    case PROP_CONTENT_TYPE:
-+        g_warning ("No support for setting content type");
-+        break;
-+    default:
-+        G_OBJECT_WARN_INVALID_PROPERTY_ID (portal_context, prop_id, pspec);
-+    }
-+}
-+
-+static gboolean
-+ibus_portal_context_g_authorize_method (GDBusInterfaceSkeleton *interface,
-+                                        GDBusMethodInvocation  *invocation)
-+{
-+    IBusPortalContext *portal_context = (IBusPortalContext *)interface;
-+
-+    if (g_strcmp0 (g_dbus_method_invocation_get_sender (invocation),
-+                   portal_context->owner) == 0) {
-+        return TRUE;
-+    }
-+
-+    g_dbus_method_invocation_return_error (invocation,
-+                                           G_DBUS_ERROR,
-+                                           G_DBUS_ERROR_FAILED,
-+                                           "Access denied");
-+    return FALSE;
-+}
-+
-+
-+static void
-+ibus_portal_context_class_init (IBusPortalContextClass *klass)
-+{
-+    GObjectClass *gobject_class;
-+    GDBusInterfaceSkeletonClass *skeleton_class;
-+
-+    gobject_class = G_OBJECT_CLASS (klass);
-+    gobject_class->finalize  = ibus_portal_context_finalize;
-+    gobject_class->set_property  =
-+            (GObjectSetPropertyFunc) ibus_portal_context_set_property;
-+    gobject_class->get_property  =
-+            (GObjectGetPropertyFunc) ibus_portal_context_get_property;
-+
-+    skeleton_class = G_DBUS_INTERFACE_SKELETON_CLASS(klass);
-+    skeleton_class->g_authorize_method = ibus_portal_context_g_authorize_method;
-+
-+    ibus_dbus_input_context_override_properties (gobject_class,
-+                                                 PROP_CONTENT_TYPE);
-+}
-+
-+static void
-+portal_context_g_signal (GDBusProxy        *proxy,
-+                         const gchar       *sender_name,
-+                         const gchar       *signal_name,
-+                         GVariant          *parameters,
-+                         IBusPortalContext *portal_context)
-+{
-+    GError *error = NULL;
-+    GDBusConnection *connection;
-+
-+    if (g_strcmp0 (sender_name, IBUS_SERVICE_IBUS) != 0)
-+        return;
-+
-+    connection = g_dbus_interface_skeleton_get_connection (
-+            G_DBUS_INTERFACE_SKELETON (portal_context));
-+    if (!g_dbus_connection_emit_signal (connection,
-+                                        portal_context->owner,
-+                                        portal_context->object_path,
-+                                        IBUS_INTERFACE_INPUT_CONTEXT,
-+                                        signal_name,
-+                                        parameters,
-+                                        &error)) {
-+        g_warning ("Unable to emit signal %s: %s", signal_name, error->message);
-+        g_error_free (error);
-+    }
-+
-+    g_signal_stop_emission_by_name (proxy, "g-signal");
-+}
-+
-+static gboolean
-+ibus_portal_context_handle_destroy (IBusDbusService       *object,
-+                                    GDBusMethodInvocation *invocation,
-+                                    IBusPortalContext     *portal_context)
-+{
-+    g_object_unref (portal_context);
-+}
-+
-+static IBusPortalContext *
-+ibus_portal_context_new (IBusInputContext *context,
-+                         GDBusConnection  *connection,
-+                         const char       *owner,
-+                         GError          **error)
-+{
-+    IBusPortalContext *portal_context =
-+            g_object_new (ibus_portal_context_get_type (), NULL);
-+
-+    g_signal_connect (context,
-+                      "g-signal",
-+                      G_CALLBACK(portal_context_g_signal),
-+                      portal_context);
-+
-+    portal_context->id = ++next_context_id;
-+    portal_context->context = g_object_ref (context);
-+    portal_context->owner = g_strdup (owner);
-+    portal_context->object_path =
-+            g_strdup_printf (IBUS_PATH_INPUT_CONTEXT, portal_context->id);
-+    portal_context->service = ibus_dbus_service_skeleton_new ();
-+
-+    g_signal_connect (portal_context->service,
-+                      "handle-destroy",
-+                      G_CALLBACK (ibus_portal_context_handle_destroy),
-+                      portal_context);
-+
-+    if (!g_dbus_interface_skeleton_export (
-+                G_DBUS_INTERFACE_SKELETON (portal_context->service),
-+                connection, portal_context->object_path,
-+                error) ||
-+        !g_dbus_interface_skeleton_export (
-+                G_DBUS_INTERFACE_SKELETON (portal_context),
-+                connection, portal_context->object_path,
-+                error)) {
-+        g_object_unref (portal_context);
-+        return NULL;
-+    }
-+
-+    all_contexts = g_list_prepend (all_contexts, portal_context);
-+
-+    return portal_context;
-+}
-+
-+GType ibus_portal_get_type (void) G_GNUC_CONST;
-+static void ibus_portal_iface_init (IBusDbusPortalIface *iface);
-+
-+G_DEFINE_TYPE_WITH_CODE (IBusPortal, ibus_portal,
-+                         IBUS_DBUS_TYPE_PORTAL_SKELETON,
-+                         G_IMPLEMENT_INTERFACE (IBUS_DBUS_TYPE_PORTAL,
-+                                                ibus_portal_iface_init));
-+
-+
-+static void
-+create_input_context_done (IBusBus               *bus,
-+                           GAsyncResult          *res,
-+                           GDBusMethodInvocation *invocation)
-+{
-+    GError *error = NULL;
-+    IBusInputContext *context;
-+    IBusPortalContext *portal_context;
-+    char *object_path;
-+
-+    context = ibus_bus_create_input_context_async_finish (ibus_bus,
-+                                                          res,
-+                                                          &error);
-+    if (context == NULL) {
-+        g_dbus_method_invocation_return_gerror (invocation, error);
-+        g_error_free (error);
-+        return;
-+    }
-+
-+    portal_context = ibus_portal_context_new (
-+            context,
-+            g_dbus_method_invocation_get_connection (invocation),
-+            g_dbus_method_invocation_get_sender (invocation),
-+            &error);
-+    g_object_unref (context);
-+
-+    if (portal_context == NULL) {
-+        g_dbus_method_invocation_return_gerror (invocation, error);
-+        g_error_free (error);
-+        g_object_unref (portal_context);
-+        return;
-+    }
-+
-+    ibus_dbus_portal_complete_create_input_context (
-+            IBUS_DBUS_PORTAL(ibus_portal),
-+            invocation, portal_context->object_path);
-+}
-+
-+static gboolean
-+ibus_portal_handle_create_input_context (IBusDbusPortal        *object,
-+                                         GDBusMethodInvocation *invocation,
-+                                         const gchar           *arg_client_name)
-+{
-+    ibus_bus_create_input_context_async (
-+            ibus_bus,
-+            arg_client_name, -1,
-+            NULL,
-+            (GAsyncReadyCallback)create_input_context_done,
-+            invocation);
-+    return TRUE;
-+}
-+
-+static void
-+ibus_portal_iface_init (IBusDbusPortalIface *iface)
-+{
-+    iface->handle_create_input_context =
-+            ibus_portal_handle_create_input_context;
-+}
-+
-+static void
-+ibus_portal_init (IBusPortal *portal)
-+{
-+}
-+
-+static void
-+ibus_portal_class_init (IBusPortalClass *klass)
-+{
-+}
-+
-+
-+static void
-+show_version_and_quit (void)
-+{
-+    g_print ("%s - Version %s\n", g_get_application_name (), VERSION);
-+    exit (EXIT_SUCCESS);
-+}
-+
-+static const GOptionEntry entries[] =
-+{
-+    { "version",   'V', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
-+      show_version_and_quit, "Show the application's version.", NULL },
-+    { "verbose",   'v', 0, G_OPTION_ARG_NONE, 
-+      &opt_verbose,   "verbose.", NULL },
-+    { "replace",   'r', 0, G_OPTION_ARG_NONE,
-+      &opt_replace,   "Replace.", NULL },
-+    { NULL },
-+};
-+
-+static void
-+on_bus_acquired (GDBusConnection *connection,
-+                 const gchar     *name,
-+                 gpointer         user_data)
-+{
-+    GError *error = NULL;
-+
-+    ibus_portal = g_object_new (ibus_portal_get_type (), NULL);
-+
-+    if (!g_dbus_interface_skeleton_export (
-+                G_DBUS_INTERFACE_SKELETON (ibus_portal),
-+                connection,
-+                IBUS_PATH_IBUS,
-+                &error)) {
-+        g_warning ("Error exporting portal: %s", error->message);
-+        g_error_free (error);
-+        return;
-+    }
-+}
-+
-+static void
-+on_name_acquired (GDBusConnection *connection,
-+                  const gchar     *name,
-+                  gpointer         user_data)
-+{
-+}
-+
-+static void
-+on_name_lost (GDBusConnection *connection,
-+              const gchar     *name,
-+              gpointer         user_data)
-+{
-+    g_main_loop_quit (loop);
-+}
-+
-+static void
-+name_owner_changed (GDBusConnection *connection,
-+                    const gchar     *sender_name,
-+                    const gchar     *object_path,
-+                    const gchar     *interface_name,
-+                    const gchar     *signal_name,
-+                    GVariant        *parameters,
-+                    gpointer         user_data)
-+{
-+  const char *name, *from, *to;
-+
-+  g_variant_get (parameters, "(sss)", &name, &from, &to);
-+
-+  if (name[0] == ':' &&
-+      g_strcmp0 (name, from) == 0 &&
-+      g_strcmp0 (to, "") == 0)
-+    {
-+        GList *l, *next;
-+        /* Client disconnected, free any input contexts it may have */
-+        for (l = all_contexts; l != NULL; l = next) {
-+            IBusPortalContext *portal_context = l->data;
-+            next = l->next;
-+
-+            if (g_strcmp0 (portal_context->owner, name) == 0) {
-+                g_object_unref (portal_context);
-+            }
-+        }
-+    }
-+}
-+
-+static void
-+_bus_disconnected_cb (IBusBus            *ibusbus)
-+{
-+    g_main_loop_quit (loop);
-+}
-+
-+gint
-+main (gint argc, gchar **argv)
-+{
-+    GDBusConnection *session_bus = NULL;
-+    guint owner_id;
-+
-+    setlocale (LC_ALL, "");
-+
-+    GOptionContext *context = g_option_context_new ("- ibus daemon");
-+    g_option_context_add_main_entries (context, entries, "ibus-daemon");
-+
-+    GError *error = NULL;
-+    if (!g_option_context_parse (context, &argc, &argv, &error)) {
-+        g_printerr ("Option parsing failed: %s\n", error->message);
-+        g_error_free (error);
-+        exit (-1);
-+    }
-+
-+    /* Avoid even loading gvfs to avoid accidental confusion */
-+    g_setenv ("GIO_USE_VFS", "local", TRUE);
-+
-+    ibus_init ();
-+
-+    ibus_set_log_handler (opt_verbose);
-+
-+    ibus_bus = ibus_bus_new ();
-+    if (!ibus_bus_is_connected (ibus_bus)) {
-+        g_printerr ("Not connected to the ibus bus\n");
-+        exit (1);
-+    }
-+
-+    g_signal_connect (ibus_bus, "disconnected",
-+                      G_CALLBACK (_bus_disconnected_cb), NULL);
-+
-+    loop = g_main_loop_new (NULL, FALSE);
-+
-+    session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
-+    if (session_bus == NULL) {
-+        g_printerr ("No session bus: %s", error->message);
-+        exit (-1);
-+    }
-+
-+    g_dbus_connection_signal_subscribe (session_bus,
-+                                        "org.freedesktop.DBus",
-+                                        "org.freedesktop.DBus",
-+                                        "NameOwnerChanged",
-+                                        "/org/freedesktop/DBus",
-+                                        NULL,
-+                                        G_DBUS_SIGNAL_FLAGS_NONE,
-+                                        name_owner_changed,
-+                                        NULL, NULL);
-+
-+    owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
-+                               IBUS_SERVICE_PORTAL,
-+                               G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
-+                               (opt_replace ? G_BUS_NAME_OWNER_FLAGS_REPLACE
-+                                            : 0),
-+                               on_bus_acquired,
-+                               on_name_acquired,
-+                               on_name_lost,
-+                               NULL,
-+                               NULL);
-+
-+    g_main_loop_run (loop);
-+
-+    g_bus_unown_name (owner_id);
-+    g_main_loop_unref (loop);
-+
-+    return 0;
-+}
-diff --git a/src/ibusshare.h b/src/ibusshare.h
-index bca477c0..f3e2011e 100644
---- a/src/ibusshare.h
-+++ b/src/ibusshare.h
-@@ -52,6 +52,13 @@
- #define IBUS_SERVICE_IBUS       "org.freedesktop.IBus"
- 
- /**
-+ * IBUS_SERVICE_PORTAL:
-+ *
-+ * Address of IBus portalservice.
-+ */
-+#define IBUS_SERVICE_PORTAL     "org.freedesktop.portal.IBus"
-+
-+/**
-  * IBUS_SERVICE_PANEL:
-  *
-  * Address of IBus panel service.
-@@ -122,6 +129,13 @@
- #define IBUS_INTERFACE_IBUS     "org.freedesktop.IBus"
- 
- /**
-+ * IBUS_INTERFACE_PORTAL:
-+ *
-+ * D-Bus interface for IBus portal.
-+ */
-+#define IBUS_INTERFACE_PORTAL   "org.freedesktop.IBus.Portal"
-+
-+/**
-  * IBUS_INTERFACE_INPUT_CONTEXT:
-  *
-  * D-Bus interface for IBus input context.
--- 
-2.13.4
-
-From 35ce62474fa97a5460d72c360943700a413a07ae Mon Sep 17 00:00:00 2001
-From: Alexander Larsson <alexl@redhat.com>
-Date: Thu, 31 Aug 2017 12:03:37 +0900
-Subject: [PATCH 04/14] Support the portal in the gtk im modules
-
-This adds a new way to create an IbusBus, ibus_bus_new_async_client().
-This returns an object that is not guarantee to handle any calls
-that are not needed by a client, meaning CreateInputContext and
-handling the input context.
-
-If you are running in a flatpak, or if IBUS_USE_PORTAL is set, then
-instead of talking to the regular ibus bus we connect to
-org.freedesktop.portal.IBus on the session bus and use the
-limited org.freedesktop.IBus.Portal interface instead of the
-org.freedesktop.IBus interface.
-
-This allows flatpaks (or other sandbox systems) to safely use
-dbus clients (apps).
-
-BUG=https://github.com/flatpak/flatpak/issues/675
-
-Review URL: https://codereview.appspot.com/328410043
-
-Patch from Alexander Larsson <alexl@redhat.com>.
----
- client/gtk2/ibusimcontext.c |   4 +-
- src/ibusbus.c               | 248 +++++++++++++++++++++++++++++++++++++++-----
- src/ibusbus.h               |  23 ++++
- src/ibusinputcontext.c      |  12 ++-
- 4 files changed, 256 insertions(+), 31 deletions(-)
-
-diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c
-index 41c7a3af..b4ca8828 100644
---- a/client/gtk2/ibusimcontext.c
-+++ b/client/gtk2/ibusimcontext.c
-@@ -583,7 +583,7 @@ ibus_im_context_class_init (IBusIMContextClass *class)
- 
-     /* init bus object */
-     if (_bus == NULL) {
--        _bus = ibus_bus_new_async ();
-+        _bus = ibus_bus_new_async_client ();
- 
-         /* init the global fake context */
-         if (ibus_bus_is_connected (_bus)) {
-@@ -603,7 +603,7 @@ ibus_im_context_class_init (IBusIMContextClass *class)
-     }
- 
-     _daemon_name_watch_id = g_bus_watch_name (G_BUS_TYPE_SESSION,
--                                              IBUS_SERVICE_IBUS,
-+                                              ibus_bus_get_service_name (_bus),
-                                               G_BUS_NAME_WATCHER_FLAGS_NONE,
-                                               daemon_name_appeared,
-                                               daemon_name_vanished,
-diff --git a/src/ibusbus.c b/src/ibusbus.c
-index 75406a37..fc0c9033 100644
---- a/src/ibusbus.c
-+++ b/src/ibusbus.c
-@@ -48,12 +48,14 @@ enum {
- enum {
-     PROP_0 = 0,
-     PROP_CONNECT_ASYNC,
-+    PROP_CLIENT_ONLY,
- };
- 
- /* IBusBusPriv */
- struct _IBusBusPrivate {
-     GFileMonitor *monitor;
-     GDBusConnection *connection;
-+    gboolean connected;
-     gboolean watch_dbus_signal;
-     guint watch_dbus_signal_id;
-     gboolean watch_ibus_signal;
-@@ -62,7 +64,10 @@ struct _IBusBusPrivate {
-     gchar *unique_name;
-     gboolean connect_async;
-     gchar *bus_address;
-+    gboolean use_portal;
-+    gboolean client_only;
-     GCancellable *cancellable;
-+    guint portal_name_watch_id;
- };
- 
- static guint    bus_signals[LAST_SIGNAL] = { 0 };
-@@ -74,6 +79,7 @@ static GObject  *ibus_bus_constructor           (GType                   type,
-                                                  guint                   n_params,
-                                                  GObjectConstructParam  *params);
- static void      ibus_bus_destroy               (IBusObject             *object);
-+static void      ibus_bus_connect_async         (IBusBus                *bus);
- static void      ibus_bus_watch_dbus_signal     (IBusBus                *bus);
- static void      ibus_bus_unwatch_dbus_signal   (IBusBus                *bus);
- static void      ibus_bus_watch_ibus_signal     (IBusBus                *bus);
-@@ -117,8 +123,10 @@ ibus_bus_class_init (IBusBusClass *class)
-     IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (class);
- 
-     gobject_class->constructor = ibus_bus_constructor;
--    gobject_class->set_property = (GObjectSetPropertyFunc) ibus_bus_set_property;
--    gobject_class->get_property = (GObjectGetPropertyFunc) ibus_bus_get_property;
-+    gobject_class->set_property =
-+            (GObjectSetPropertyFunc) ibus_bus_set_property;
-+    gobject_class->get_property =
-+            (GObjectGetPropertyFunc) ibus_bus_get_property;
-     ibus_object_class->destroy = ibus_bus_destroy;
- 
-     /* install properties */
-@@ -128,13 +136,28 @@ ibus_bus_class_init (IBusBusClass *class)
-      * Whether the #IBusBus object should connect asynchronously to the bus.
-      *
-      */
--    g_object_class_install_property (gobject_class,
--                                     PROP_CONNECT_ASYNC,
--                                     g_param_spec_boolean ("connect-async",
--                                                           "Connect Async",
--                                                           "Connect asynchronously to the bus",
--                                                           FALSE,
--                                                           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-+    g_object_class_install_property (
-+            gobject_class,
-+            PROP_CONNECT_ASYNC,
-+            g_param_spec_boolean ("connect-async",
-+                                  "Connect Async",
-+                                  "Connect asynchronously to the bus",
-+                                  FALSE,
-+                                  G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-+    /**
-+     * IBusBus:client-only:
-+     *
-+     * Whether the #IBusBus object is for client use only.
-+     *
-+     */
-+    g_object_class_install_property (
-+            gobject_class,
-+            PROP_CLIENT_ONLY,
-+            g_param_spec_boolean ("client-only",
-+                                  "ClientOnly",
-+                                  "Client use only",
-+                                  FALSE,
-+                                  G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
- 
-     /* install signals */
-     /**
-@@ -294,6 +317,8 @@ ibus_bus_close_connection (IBusBus *bus)
-     g_cancellable_cancel (bus->priv->cancellable);
-     g_cancellable_reset (bus->priv->cancellable);
- 
-+    bus->priv->connected = FALSE;
-+
-     /* unref the old connection at first */
-     if (bus->priv->connection != NULL) {
-         g_signal_handlers_disconnect_by_func (bus->priv->connection,
-@@ -311,6 +336,8 @@ static void
- ibus_bus_connect_completed (IBusBus *bus)
- {
-     g_assert (bus->priv->connection);
-+
-+    bus->priv->connected = TRUE;
-     /* FIXME */
-     ibus_bus_hello (bus);
- 
-@@ -329,9 +356,38 @@ ibus_bus_connect_completed (IBusBus *bus)
- }
- 
- static void
-+_bus_connect_start_portal_cb (GObject      *source_object,
-+                              GAsyncResult *res,
-+                              gpointer      user_data)
-+{
-+    IBusBus *bus = IBUS_BUS (user_data);
-+    GVariant *result;
-+    GError *error = NULL;
-+
-+    result = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object),
-+                                            res,
-+                                            &error);
-+    if (result != NULL) {
-+        ibus_bus_connect_completed (bus);
-+        g_variant_unref (result);
-+    } else {
-+        g_error_free (error);
-+
-+        g_dbus_connection_close (bus->priv->connection, NULL, NULL, NULL);
-+        g_object_unref (bus->priv->connection);
-+        bus->priv->connection = NULL;
-+
-+        g_free (bus->priv->bus_address);
-+        bus->priv->bus_address = NULL;
-+    }
-+
-+    g_object_unref (bus);
-+}
-+
-+static void
- _bus_connect_async_cb (GObject      *source_object,
--                        GAsyncResult *res,
--                        gpointer      user_data)
-+                       GAsyncResult *res,
-+                       gpointer      user_data)
- {
-     g_return_if_fail (user_data != NULL);
-     g_return_if_fail (IBUS_IS_BUS (user_data));
-@@ -349,7 +405,26 @@ _bus_connect_async_cb (GObject      *source_object,
-     }
- 
-     if (bus->priv->connection != NULL) {
--        ibus_bus_connect_completed (bus);
-+        if (bus->priv->use_portal) {
-+            g_object_set_data (G_OBJECT (bus->priv->connection),
-+                               "ibus-portal-connection",
-+                               GINT_TO_POINTER (TRUE));
-+            g_dbus_connection_call (
-+                    bus->priv->connection,
-+                    IBUS_SERVICE_PORTAL,
-+                    IBUS_PATH_IBUS,
-+                    "org.freedesktop.DBus.Peer",
-+                    "Ping",
-+                    g_variant_new ("()"),
-+                    G_VARIANT_TYPE ("()"),
-+                    G_DBUS_CALL_FLAGS_NONE,
-+                    -1,
-+                    bus->priv->cancellable,
-+                    (GAsyncReadyCallback) _bus_connect_start_portal_cb,
-+                    g_object_ref (bus));
-+        } else {
-+            ibus_bus_connect_completed (bus);
-+        }
-     }
-     else {
-         g_free (bus->priv->bus_address);
-@@ -360,21 +435,32 @@ _bus_connect_async_cb (GObject      *source_object,
-     g_object_unref (bus);
- }
- 
-+static gchar *
-+ibus_bus_get_bus_address (IBusBus *bus)
-+{
-+    if (_bus->priv->use_portal)
-+        return g_dbus_address_get_for_bus_sync (G_BUS_TYPE_SESSION, NULL, NULL);
-+    else
-+        return g_strdup (ibus_get_address ());
-+}
-+
- static void
- ibus_bus_connect_async (IBusBus *bus)
- {
--    const gchar *bus_address = ibus_get_address ();
-+    gchar *bus_address = ibus_bus_get_bus_address (bus);
- 
-     if (bus_address == NULL)
-         return;
- 
--    if (g_strcmp0 (bus->priv->bus_address, bus_address) == 0)
-+    if (g_strcmp0 (bus->priv->bus_address, bus_address) == 0) {
-+        g_free (bus_address);
-         return;
-+    }
- 
-     /* Close current connection and cancel ongoing connect request. */
-     ibus_bus_close_connection (bus);
- 
--    bus->priv->bus_address = g_strdup (bus_address);
-+    bus->priv->bus_address = bus_address;
-     g_object_ref (bus);
-     g_dbus_connection_new_for_address (
-             bus_address,
-@@ -385,6 +471,28 @@ ibus_bus_connect_async (IBusBus *bus)
-             _bus_connect_async_cb, bus);
- }
- 
-+static gboolean
-+is_in_flatpak (void)
-+{
-+    static gboolean flatpak_info_read;
-+    static gboolean in_flatpak;
-+
-+    if (flatpak_info_read)
-+        return in_flatpak;
-+
-+    flatpak_info_read = TRUE;
-+    if (g_file_test ("/.flatpak-info", G_FILE_TEST_EXISTS))
-+        in_flatpak = TRUE;
-+    return in_flatpak;
-+}
-+
-+static gboolean
-+ibus_bus_should_connect_portal (IBusBus *bus)
-+{
-+    return bus->priv->client_only &&
-+        (is_in_flatpak () || g_getenv ("IBUS_USE_PORTAL") != NULL);
-+}
-+
- static void
- ibus_bus_connect (IBusBus *bus)
- {
-@@ -431,7 +539,6 @@ ibus_bus_init (IBusBus *bus)
- {
-     struct stat buf;
-     gchar *path;
--    GFile *file;
- 
-     bus->priv = IBUS_BUS_GET_PRIVATE (bus);
- 
-@@ -443,6 +550,7 @@ ibus_bus_init (IBusBus *bus)
-     bus->priv->watch_ibus_signal_id = 0;
-     bus->priv->unique_name = NULL;
-     bus->priv->connect_async = FALSE;
-+    bus->priv->client_only = FALSE;
-     bus->priv->bus_address = NULL;
-     bus->priv->cancellable = g_cancellable_new ();
- 
-@@ -453,17 +561,12 @@ ibus_bus_init (IBusBus *bus)
- 
-     if (stat (path, &buf) == 0) {
-         if (buf.st_uid != getuid ()) {
--            g_warning ("The owner of %s is not %s!", path, ibus_get_user_name ());
-+            g_warning ("The owner of %s is not %s!",
-+                       path, ibus_get_user_name ());
-             return;
-         }
-     }
- 
--    file = g_file_new_for_path (ibus_get_socket_path ());
--    bus->priv->monitor = g_file_monitor_file (file, 0, NULL, NULL);
--
--    g_signal_connect (bus->priv->monitor, "changed", (GCallback) _changed_cb, bus);
--
--    g_object_unref (file);
-     g_free (path);
- }
- 
-@@ -477,6 +580,9 @@ ibus_bus_set_property (IBusBus      *bus,
-     case PROP_CONNECT_ASYNC:
-         bus->priv->connect_async = g_value_get_boolean (value);
-         break;
-+    case PROP_CLIENT_ONLY:
-+        bus->priv->client_only = g_value_get_boolean (value);
-+        break;
-     default:
-         G_OBJECT_WARN_INVALID_PROPERTY_ID (bus, prop_id, pspec);
-     }
-@@ -492,25 +598,73 @@ ibus_bus_get_property (IBusBus    *bus,
-     case PROP_CONNECT_ASYNC:
-         g_value_set_boolean (value, bus->priv->connect_async);
-         break;
-+    case PROP_CLIENT_ONLY:
-+        g_value_set_boolean (value, bus->priv->client_only);
-+        break;
-     default:
-         G_OBJECT_WARN_INVALID_PROPERTY_ID (bus, prop_id, pspec);
-     }
- }
- 
-+static void
-+portal_name_appeared (GDBusConnection *connection,
-+                      const gchar     *name,
-+                      const gchar     *owner,
-+                      gpointer         user_data)
-+{
-+    IBusBus *bus = IBUS_BUS (user_data);
-+
-+    if (bus->priv->connection == NULL)
-+        ibus_bus_connect_async (bus);
-+}
-+
-+static void
-+portal_name_vanished (GDBusConnection *connection,
-+                      const gchar     *name,
-+                      gpointer         user_data)
-+{
-+    IBusBus *bus = IBUS_BUS (user_data);
-+
-+    if (bus->priv->connection)
-+        g_dbus_connection_close (bus->priv->connection, NULL, NULL, NULL);
-+}
-+
-+
- static GObject*
- ibus_bus_constructor (GType                  type,
-                       guint                  n_params,
-                       GObjectConstructParam *params)
- {
-     GObject *object;
-+    GFile *file;
- 
-     /* share one IBusBus instance in whole application */
-     if (_bus == NULL) {
--        object = G_OBJECT_CLASS (ibus_bus_parent_class)->constructor (type, n_params, params);
-+        object = G_OBJECT_CLASS (ibus_bus_parent_class)->constructor (
-+                type, n_params, params);
-         /* make bus object sink */
-         g_object_ref_sink (object);
-         _bus = IBUS_BUS (object);
- 
-+        _bus->priv->use_portal = ibus_bus_should_connect_portal (_bus);
-+
-+        if (!_bus->priv->use_portal) {
-+            file = g_file_new_for_path (ibus_get_socket_path ());
-+            _bus->priv->monitor = g_file_monitor_file (file, 0, NULL, NULL);
-+            g_signal_connect (_bus->priv->monitor, "changed",
-+                              (GCallback) _changed_cb, _bus);
-+            g_object_unref (file);
-+        } else {
-+            _bus->priv->portal_name_watch_id =
-+                g_bus_watch_name (G_BUS_TYPE_SESSION,
-+                                  IBUS_SERVICE_PORTAL,
-+                                  G_BUS_NAME_WATCHER_FLAGS_NONE,
-+                                  portal_name_appeared,
-+                                  portal_name_vanished,
-+                                  _bus, NULL);
-+        }
-+
-+
-         if (_bus->priv->connect_async)
-             ibus_bus_connect_async (_bus);
-         else
-@@ -561,6 +715,11 @@ ibus_bus_destroy (IBusObject *object)
-     g_object_unref (bus->priv->cancellable);
-     bus->priv->cancellable = NULL;
- 
-+    if (bus->priv->portal_name_watch_id) {
-+        g_bus_unwatch_name (bus->priv->portal_name_watch_id);
-+        bus->priv->portal_name_watch_id = 0;
-+    }
-+
-     IBUS_OBJECT_CLASS (ibus_bus_parent_class)->destroy (object);
- }
- 
-@@ -656,6 +815,7 @@ ibus_bus_new (void)
- {
-     IBusBus *bus = IBUS_BUS (g_object_new (IBUS_TYPE_BUS,
-                                            "connect-async", FALSE,
-+                                           "client-only", FALSE,
-                                            NULL));
- 
-     return bus;
-@@ -666,6 +826,18 @@ ibus_bus_new_async (void)
- {
-     IBusBus *bus = IBUS_BUS (g_object_new (IBUS_TYPE_BUS,
-                                            "connect-async", TRUE,
-+                                           "client-only", FALSE,
-+                                           NULL));
-+
-+    return bus;
-+}
-+
-+IBusBus *
-+ibus_bus_new_async_client (void)
-+{
-+    IBusBus *bus = IBUS_BUS (g_object_new (IBUS_TYPE_BUS,
-+                                           "connect-async", TRUE,
-+                                           "client-only", TRUE,
-                                            NULL));
- 
-     return bus;
-@@ -679,7 +851,7 @@ ibus_bus_is_connected (IBusBus *bus)
-     if (bus->priv->connection == NULL || g_dbus_connection_is_closed (bus->priv->connection))
-         return FALSE;
- 
--    return TRUE;
-+    return bus->priv->connected;
- }
- 
- IBusInputContext *
-@@ -795,9 +967,9 @@ ibus_bus_create_input_context_async (IBusBus            *bus,
-      * 2. New local IBusInputContext proxy of the remote IC
-      */
-     g_dbus_connection_call (bus->priv->connection,
--            IBUS_SERVICE_IBUS,
-+            ibus_bus_get_service_name (bus),
-             IBUS_PATH_IBUS,
--            IBUS_INTERFACE_IBUS,
-+            bus->priv->use_portal ? IBUS_INTERFACE_PORTAL : IBUS_INTERFACE_IBUS,
-             "CreateInputContext",
-             g_variant_new ("(s)", client_name),
-             G_VARIANT_TYPE("(o)"),
-@@ -1454,6 +1626,14 @@ ibus_bus_get_connection (IBusBus *bus)
-     return bus->priv->connection;
- }
- 
-+const gchar *
-+ibus_bus_get_service_name (IBusBus *bus)
-+{
-+    if (bus->priv->use_portal)
-+        return IBUS_SERVICE_PORTAL;
-+    return IBUS_SERVICE_IBUS;
-+}
-+
- gboolean
- ibus_bus_exit (IBusBus *bus,
-                gboolean restart)
-@@ -2369,6 +2549,13 @@ ibus_bus_call_sync (IBusBus            *bus,
-     g_assert (member != NULL);
-     g_return_val_if_fail (ibus_bus_is_connected (bus), NULL);
- 
-+    if (bus->priv->use_portal &&
-+        g_strcmp0 (bus_name, IBUS_SERVICE_IBUS) == 0)  {
-+        bus_name = IBUS_SERVICE_PORTAL;
-+        if (g_strcmp0 (interface, IBUS_INTERFACE_IBUS) == 0)
-+            interface = IBUS_INTERFACE_PORTAL;
-+    }
-+
-     GError *error = NULL;
-     GVariant *result;
-     result = g_dbus_connection_call_sync (bus->priv->connection,
-@@ -2436,6 +2623,13 @@ ibus_bus_call_async (IBusBus            *bus,
-     task = g_task_new (bus, cancellable, callback, user_data);
-     g_task_set_source_tag (task, source_tag);
- 
-+    if (bus->priv->use_portal &&
-+        g_strcmp0 (bus_name, IBUS_SERVICE_IBUS) == 0)  {
-+        bus_name = IBUS_SERVICE_PORTAL;
-+        if (g_strcmp0 (interface, IBUS_INTERFACE_IBUS) == 0)
-+            interface = IBUS_INTERFACE_PORTAL;
-+    }
-+
-     g_dbus_connection_call (bus->priv->connection,
-                             bus_name,
-                             path,
-diff --git a/src/ibusbus.h b/src/ibusbus.h
-index 9f65d36a..dff3dfb7 100644
---- a/src/ibusbus.h
-+++ b/src/ibusbus.h
-@@ -105,6 +105,19 @@ IBusBus     *ibus_bus_new               (void);
-  */
- IBusBus     *ibus_bus_new_async         (void);
- 
-+/**
-+ * ibus_bus_new_async_client:
-+ *
-+ * Creates a new #IBusBus instance for client use only. It will possibly
-+ * be limited in what it can do.
-+ *
-+ * The instance will asynchronously connect to the IBus daemon.
-+ *
-+ * Returns: A newly allocated #IBusBus instance, and the instance is not
-+ * floating.
-+ */
-+IBusBus     *ibus_bus_new_async_client  (void);
-+
- 
- /**
-  * ibus_bus_is_connected:
-@@ -128,6 +141,16 @@ GDBusConnection *
-              ibus_bus_get_connection    (IBusBus        *bus);
- 
- /**
-+ * ibus_bus_get_service_name:
-+ * @bus: An #IBusBus.
-+ *
-+ * Return the main service name to use for calls on the ibus connection.
-+ *
-+ * Returns: at dbus name.
-+ */
-+const gchar * ibus_bus_get_service_name (IBusBus        *bus);
-+
-+/**
-  * ibus_bus_hello:
-  * @bus: An #IBusBus.
-  *
-diff --git a/src/ibusinputcontext.c b/src/ibusinputcontext.c
-index 9a50acc0..ae7048ad 100644
---- a/src/ibusinputcontext.c
-+++ b/src/ibusinputcontext.c
-@@ -684,16 +684,20 @@ ibus_input_context_new (const gchar     *path,
- {
-     g_assert (path != NULL);
-     g_assert (G_IS_DBUS_CONNECTION (connection));
-+    const gchar *service_name = IBUS_SERVICE_IBUS;
- 
-     GInitable *initable;
- 
-     GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START;
- 
-+    if (g_object_get_data (G_OBJECT (connection), "ibus-portal-connection"))
-+        service_name = IBUS_SERVICE_PORTAL;
-+
-     initable = g_initable_new (IBUS_TYPE_INPUT_CONTEXT,
-                                cancellable,
-                                error,
-                                "g-connection",      connection,
--                               "g-name",            IBUS_SERVICE_IBUS,
-+                               "g-name",            service_name,
-                                "g-flags",           flags,
-                                "g-interface-name",  IBUS_INTERFACE_INPUT_CONTEXT,
-                                "g-object-path",     path,
-@@ -714,16 +718,20 @@ ibus_input_context_new_async (const gchar         *path,
-     g_assert (path != NULL);
-     g_assert (G_IS_DBUS_CONNECTION (connection));
-     g_assert (callback != NULL);
-+    const gchar *service_name = IBUS_SERVICE_IBUS;
- 
-     GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START;
- 
-+    if (g_object_get_data (G_OBJECT (connection), "ibus-portal-connection"))
-+        service_name = IBUS_SERVICE_PORTAL;
-+
-     g_async_initable_new_async (IBUS_TYPE_INPUT_CONTEXT,
-                                 G_PRIORITY_DEFAULT,
-                                 cancellable,
-                                 callback,
-                                 user_data,
-                                 "g-connection",      connection,
--                                "g-name",            IBUS_SERVICE_IBUS,
-+                                "g-name",            service_name,
-                                 "g-flags",           flags,
-                                 "g-interface-name",  IBUS_INTERFACE_INPUT_CONTEXT,
-                                 "g-object-path",     path,
--- 
-2.13.4
-
-From 9772e800f3e6937510f2609c5ce9a6860c59cb81 Mon Sep 17 00:00:00 2001
-From: Alexander Larsson <alexl@redhat.com>
-Date: Mon, 4 Sep 2017 12:02:17 +0900
-Subject: [PATCH 05/14] test: Testing in flatpak
-
-Test with:
-flatpak-builder --force-clean app org.test.IBus.json
-flatpak-builder --run --nofilesystem=host app org.test.IBus.json zenity --entry
-
-BUG=https://github.com/flatpak/flatpak/issues/675
-R=Shawn.P.Huang@gmail.com
-
-Review URL: https://codereview.appspot.com/329090043
-
-Patch from Alexander Larsson <alexl@redhat.com>.
----
- test/org.test.IBus.json | 43 +++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 43 insertions(+)
- create mode 100644 test/org.test.IBus.json
-
-diff --git a/test/org.test.IBus.json b/test/org.test.IBus.json
-new file mode 100644
-index 00000000..dc3caa62
---- /dev/null
-+++ b/test/org.test.IBus.json
-@@ -0,0 +1,43 @@
-+{
-+    "app-id": "org.test.IBus",
-+    "runtime": "org.gnome.Platform",
-+    "runtime-version": "3.24",
-+    "sdk": "org.gnome.Sdk",
-+    "command": "/usr/bin/zenity",
-+    "finish-args": [
-+        /* X11 + XShm access */
-+        "--share=ipc", "--socket=x11",
-+        /* Wayland access */
-+        "--socket=wayland",
-+        /* Needed for dconf to work */
-+        "--filesystem=xdg-run/dconf", "--filesystem=~/.config/dconf:ro",
-+        "--talk-name=ca.desrt.dconf", "--env=DCONF_USER_CONFIG_DIR=.config/dconf",
-+        "--env=GTK_IM_MODULE_FILE=/app/lib/gtk-3.0/3.0.0/immodules.cache"
-+    ],
-+    "build-options" : {
-+        "cflags": "-O2 -g",
-+        "cxxflags": "-O2 -g",
-+        "env": {
-+            "V": "1"
-+        }
-+    },
-+    "cleanup": ["/include", "/lib/pkgconfig",
-+                "/share/pkgconfig", "/share/aclocal",
-+                "/man", "/share/man", "/share/gtk-doc",
-+                "/share/vala",
-+                "*.la", "*.a"],
-+    "modules": [
-+        {
-+            "name": "ibus",
-+            "sources": [
-+                {
-+                    "type": "git",
-+                    "url": "https://github.com/alexlarsson/ibus",
-+                    "branch": "ibus-portal"
-+                }
-+            ],
-+            "config-opts": ["--disable-emoji-dict", "--disable-dconf"],
-+            "post-install": ["gtk-query-immodules-3.0 /app/lib/gtk-3.0/3.0.0/immodules/im-ibus.so > /app/lib/gtk-3.0/3.0.0/immodules.cache"]
-+        }
-+    ]
-+}
--- 
-2.13.4
-
-From 9937a0e4501ccf0cfd238ce7c97733c3099db3f7 Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Mon, 4 Sep 2017 12:19:07 +0900
-Subject: [PATCH 06/14] bus: ibus-daemon activates ibus-portal
-
-When ibus-daemon restarts, ibus-portal exits with on_name_lost() and
-the clients wait for portal_name_appeared() until ibus-poral restarts.
-Now the clients can connect to ibus-daemon with this way and also
-they don't have to activate ibus-portal.
-
-BUG=https://github.com/flatpak/flatpak/issues/675
-R=Shawn.P.Huang@gmail.com
-
-Review URL: https://codereview.appspot.com/321530043
----
- bus/server.c    | 45 +++++++++++++++++++++++++++++++++++++++++++--
- portal/portal.c |  6 +-----
- 2 files changed, 44 insertions(+), 7 deletions(-)
-
-diff --git a/bus/server.c b/bus/server.c
-index ff3ea093..e2898274 100644
---- a/bus/server.c
-+++ b/bus/server.c
-@@ -93,6 +93,45 @@ bus_new_connection_cb (GDBusServer     *server,
-     return TRUE;
- }
- 
-+static void
-+_server_connect_start_portal_cb (GObject      *source_object,
-+                                 GAsyncResult *res,
-+                                 gpointer      user_data)
-+{
-+    GVariant *result;
-+    GError *error = NULL;
-+
-+    result = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object),
-+                                            res,
-+                                            &error);
-+    if (result != NULL) {
-+        g_variant_unref (result);
-+    } else {
-+        g_print ("portal is not running: %s\n", error->message);
-+        g_error_free (error);
-+    }
-+}
-+
-+static void
-+bus_acquired_handler (GDBusConnection *connection,
-+                      const gchar     *name,
-+                      gpointer         user_data)
-+{
-+    g_dbus_connection_call (connection,
-+                            IBUS_SERVICE_PORTAL,
-+                            IBUS_PATH_IBUS,
-+                            "org.freedesktop.DBus.Peer",
-+                            "Ping",
-+                            g_variant_new ("()"),
-+                            G_VARIANT_TYPE ("()"),
-+                            G_DBUS_CALL_FLAGS_NONE,
-+                            -1,
-+                            NULL /* cancellable */,
-+                            (GAsyncReadyCallback)
-+                                    _server_connect_start_portal_cb,
-+                            NULL);
-+}
-+
- void
- bus_server_init (void)
- {
-@@ -134,8 +173,10 @@ bus_server_init (void)
-     ibus_write_address (address);
- 
-     /* own a session bus name so that third parties can easily track our life-cycle */
--    g_bus_own_name (G_BUS_TYPE_SESSION, IBUS_SERVICE_IBUS, G_BUS_NAME_OWNER_FLAGS_NONE,
--                    NULL, NULL, NULL, NULL, NULL);
-+    g_bus_own_name (G_BUS_TYPE_SESSION, IBUS_SERVICE_IBUS,
-+                    G_BUS_NAME_OWNER_FLAGS_NONE,
-+                    bus_acquired_handler,
-+                    NULL, NULL, NULL, NULL);
- }
- 
- const gchar *
-diff --git a/portal/portal.c b/portal/portal.c
-index 0415f996..cb24d257 100644
---- a/portal/portal.c
-+++ b/portal/portal.c
-@@ -101,10 +101,6 @@ _forward_method_cb (GObject *source_object,
-                     gpointer user_data)
- {
-     GDBusMethodInvocation *invocation = user_data;
--    IBusPortalContext *portal_context =
--            (IBusPortalContext *) g_dbus_method_invocation_get_user_data (
--                    invocation);
--    IBusEngineDesc *desc;
-     GError *error = NULL;
- 
-     GVariant *variant = g_dbus_proxy_call_finish ((GDBusProxy *) source_object,
-@@ -413,6 +409,7 @@ ibus_portal_context_handle_destroy (IBusDbusService       *object,
-                                     IBusPortalContext     *portal_context)
- {
-     g_object_unref (portal_context);
-+    return FALSE;
- }
- 
- static IBusPortalContext *
-@@ -475,7 +472,6 @@ create_input_context_done (IBusBus               *bus,
-     GError *error = NULL;
-     IBusInputContext *context;
-     IBusPortalContext *portal_context;
--    char *object_path;
- 
-     context = ibus_bus_create_input_context_async_finish (ibus_bus,
-                                                           res,
--- 
-2.13.4
-
-From 3e01bab972ad12b92c55a9dde554a0359c217290 Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Wed, 6 Sep 2017 12:04:52 +0900
-Subject: [PATCH 07/14] portal: Add org.freedesktop.IBus.Portal.xml in
- EXTRA_DIST
-
-Review URL: https://codereview.appspot.com/325370043
----
- portal/Makefile.am | 17 +++++++++--------
- 1 file changed, 9 insertions(+), 8 deletions(-)
-
-diff --git a/portal/Makefile.am b/portal/Makefile.am
-index 954fc591..d1e2051a 100644
---- a/portal/Makefile.am
-+++ b/portal/Makefile.am
-@@ -65,12 +65,6 @@ ibus_portal_LDADD = \
- 	$(AM_LDADD) \
- 	$(NULL)
- 
--EXTRA_DIST = \
--	$(NULL)
--
--CLEANFILES = \
--	$(NULL)
--
- $(libibus):
- 	$(MAKE) -C $(top_builddir)/src
- 
-@@ -89,7 +83,14 @@ $(ibus_dbus_built_sources) : org.freedesktop.IBus.Portal.xml
- 		$^ \
- 		$(NULL)
- 
--EXTRA_DIST += $(dbusservice_in_files)
--CLEANFILES += $(dbusservice_DATA)
-+EXTRA_DIST = \
-+    $(dbusservice_in_files) \
-+    org.freedesktop.IBus.Portal.xml \
-+    $(NULL)
-+
-+CLEANFILES = \
-+    $(dbusservice_DATA) \
-+    $(NULL)
-+
- 
- -include $(top_srcdir)/git.mk
--- 
-2.13.4
-
-From 21bac4733684ca6a74ddb02f457c0fe19eb9180d Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Wed, 6 Sep 2017 12:11:01 +0900
-Subject: [PATCH 08/14] ui/gtk3: Move ibus-emoji-dialog.vapi from ui/gtk3 to
- bindings/vala
-
-R=Shawn.P.Huang@gmail.com
-
-Review URL: https://codereview.appspot.com/322590043
----
- .../vala}/IBusEmojiDialog-1.0.metadata             |   0
- bindings/vala/Makefile.am                          | 161 +++++++++++++++++++--
- .../vala}/ibus-emoji-dialog-1.0.deps               |   0
- po/POTFILES.skip                                   |   5 +
- ui/gtk3/Makefile.am                                | 113 ++++-----------
- ui/gtk3/emojier.vala                               |  19 +--
- ui/gtk3/ibusemojidialog.h                          |  26 ++++
- 7 files changed, 213 insertions(+), 111 deletions(-)
- rename {ui/gtk3 => bindings/vala}/IBusEmojiDialog-1.0.metadata (100%)
- rename {ui/gtk3 => bindings/vala}/ibus-emoji-dialog-1.0.deps (100%)
-
-diff --git a/ui/gtk3/IBusEmojiDialog-1.0.metadata b/bindings/vala/IBusEmojiDialog-1.0.metadata
-similarity index 100%
-rename from ui/gtk3/IBusEmojiDialog-1.0.metadata
-rename to bindings/vala/IBusEmojiDialog-1.0.metadata
-diff --git a/bindings/vala/Makefile.am b/bindings/vala/Makefile.am
-index 4e34afc7..fc8e2f01 100644
---- a/bindings/vala/Makefile.am
-+++ b/bindings/vala/Makefile.am
-@@ -3,7 +3,8 @@
- # ibus - The Input Bus
- #
- # Copyright (c) 2007-2016 Peng Huang <shawn.p.huang@gmail.com>
--# Copyright (c) 2007-2016 Red Hat, Inc.
-+# Copyright (c) 2017 Takao Fujiwara <takao.fujiwara1@gmail.com>
-+# Copyright (c) 2007-2017 Red Hat, Inc.
- #
- # This library is free software; you can redistribute it and/or
- # modify it under the terms of the GNU Lesser General Public
-@@ -22,15 +23,47 @@
- 
- -include $(VAPIGEN_MAKEFILE)
- 
-+libibus = $(top_builddir)/src/libibus-@IBUS_API_VERSION@.la
-+
-+noinst_LTLIBRARIES =
-+noinst_DATA =
-+INTROSPECTION_GIRS =
-+girdir = $(datadir)/gir-1.0
-+
-+AM_CPPFLAGS = \
-+    -I$(top_srcdir)/src \
-+    -I$(top_builddir)/src \
-+    -include $(CONFIG_HEADER) \
-+    $(NULL)
-+AM_CFLAGS = \
-+    -DG_LOG_DOMAIN=\"IBUS\" \
-+    -DPKGDATADIR=\"$(pkgdatadir)\" \
-+    -DIBUS_DISABLE_DEPRECATED \
-+    -Wno-unused-variable \
-+    -Wno-unused-but-set-variable \
-+    -Wno-unused-function \
-+    $(NULL)
-+AM_VALAFLAGS = \
-+    --vapidir=$(builddir) \
-+    --vapidir=$(srcdir) \
-+    --pkg=posix \
-+    --pkg=gtk+-3.0 \
-+    --pkg=gdk-x11-3.0 \
-+    --pkg=ibus-1.0 \
-+    --pkg=config \
-+    --pkg=xi \
-+    --target-glib="$(VALA_TARGET_GLIB_VERSION)" \
-+    $(NULL)
-+
- vapi_deps = \
- 	IBus-1.0.metadata \
--	IBus-1.0-custom.vala \
- 	$(top_builddir)/src/IBus-1.0.gir \
- 	$(NULL)
- 
- ibus-1.0.vapi: $(vapi_deps)
- 
--VAPIGEN_VAPIS = ibus-1.0.vapi
-+ibus_vapi = ibus-1.0.vapi
-+VAPIGEN_VAPIS = $(ibus_vapi)
- 
- ibus_1_0_vapi_DEPS = gio-2.0
- ibus_1_0_vapi_METADATADIRS = $(srcdir)
-@@ -40,18 +73,118 @@ ibus_1_0_vapi_FILES = \
- 	$(NULL)
- 
- vapidir = $(datadir)/vala/vapi
--vapi_DATA = $(VAPIGEN_VAPIS) $(VAPIGEN_VAPIS:.vapi=.deps)
-+vapi_DATA = $(ibus_vapi) $(ibus_vapi:.vapi=.deps)
- 
--MAINTAINERCLEANFILES = $(VAPIGEN_VAPIS)
--DISTCLEANFILES = $(VAPIGEN_VAPIS)
-+MAINTAINERCLEANFILES = $(ibus_vapi)
-+DISTCLEANFILES = $(ibus_vapi)
- 
--EXTRA_DIST = \
--	$(VAPIGEN_VAPIS) \
--	IBus-1.0.metadata \
--	IBus-1.0-custom.vala \
--	ibus-1.0.deps \
--	config.vapi \
--	xi.vapi \
--	$(NULL)
-+EXTRA_DIST =                                    \
-+    $(ibus_vapi)                                \
-+    IBus-1.0.metadata                           \
-+    IBus-1.0-custom.vala                        \
-+    IBusEmojiDialog-1.0.metadata                \
-+    ibus-1.0.deps                               \
-+    ibus-emoji-dialog-1.0.deps                  \
-+    config.vapi                                 \
-+    xi.vapi                                     \
-+    $(NULL)
-+
-+if ENABLE_EMOJI_DICT
-+AM_VALAFLAGS += --define=EMOJI_DICT
-+
-+libibus_emoji_dialog = libibus-emoji-dialog-1.0.la
-+noinst_LTLIBRARIES += $(libibus_emoji_dialog)
-+
-+libibus_emoji_dialog_1_0_la_SOURCES =           \
-+    candidatearea.vala                          \
-+    emojier.vala                                \
-+    iconwidget.vala                             \
-+    pango.vala                                  \
-+    separator.vala                              \
-+    $(NULL)
-+libibus_emoji_dialog_1_0_la_CFLAGS =            \
-+    $(AM_CFLAGS)                                \
-+    @GLIB2_CFLAGS@                              \
-+    @GIO2_CFLAGS@                               \
-+    @GTHREAD2_CFLAGS@                           \
-+    @GTK3_CFLAGS@                               \
-+    @X11_CFLAGS@                                \
-+    -DBINDIR=\"$(bindir)\"                      \
-+    $(NULL)
-+libibus_emoji_dialog_1_0_la_LIBADD =            \
-+    @GLIB2_LIBS@                                \
-+    @GIO2_LIBS@                                 \
-+    @GTHREAD2_LIBS@                             \
-+    @GTK3_LIBS@                                 \
-+    @X11_LIBS@                                  \
-+    -lXi                                        \
-+    $(libibus)                                  \
-+    $(NULL)
-+libibus_emoji_dialog_1_0_la_LDFLAGS =           \
-+    -no-undefined                               \
-+    -export-symbols-regex "ibus_.*"             \
-+    $(NULL)
-+
-+# per file setting is needed to avoid conflicting LN_S by calling
-+# duplicated times in parallel make
-+%.vala: $(ibus_vapi)
-+	if test ! -f $@ ; then                                              \
-+	    $(LN_S) $(top_srcdir)/ui/gtk3/$@ .;                             \
-+	fi;
-+
-+MAINTAINERCLEANFILES += $(libibus_emoji_dialog_1_0_la_SOURCES)
-+DISTCLEANFILES += $(libibus_emoji_dialog_1_0_la_SOURCES)
-+
-+if HAVE_INTROSPECTION
-+-include $(INTROSPECTION_MAKEFILE)
-+INTROSPECTION_SCANNER_ARGS =
-+INTROSPECTION_COMPILER_ARGS =                   \
-+    --includedir=$(srcdir)                      \
-+    --includedir=.                              \
-+    --includedir=$(top_srcdir)/src              \
-+    $(NULL)
-+
-+
-+emoji_headers =                                 \
-+    $(top_srcdir)/ui/gtk3/ibusemojidialog.h     \
-+    $(NULL)
-+
-+IBusEmojiDialog-1.0.gir: $(libibus_emoji_dialog) Makefile
-+IBusEmojiDialog_1_0_gir_SCANNERFLAGS =          \
-+    --pkg-export=ibus-1.0                       \
-+    --pkg=gtk+-3.0                              \
-+    $(IBUS_GIR_SCANNERFLAGS)                    \
-+    $(NULL)
-+IBusEmojiDialog_1_0_gir_INCLUDES = Gtk-3.0 GLib-2.0 GObject-2.0 Gio-2.0
-+IBusEmojiDialog_1_0_gir_LIBS = $(libibus_emoji_dialog) $(libibus)
-+IBusEmojiDialog_1_0_gir_FILES = $(emoji_headers)
-+IBusEmojiDialog_1_0_gir_CFLAGS =                \
-+    -I$(srcdir)                                 \
-+    -I$(builddir)                               \
-+    -I$(top_srcdir)/src                         \
-+    $(NULL)
-+
-+ibus_emoji_dialog_gir = IBusEmojiDialog-1.0.gir
-+INTROSPECTION_GIRS += $(ibus_emoji_dialog_gir)
-+noinst_DATA += $(ibus_emoji_dialog_gir)
-+EXTRA_DIST += $(ibus_emoji_dialog_gir)
-+MAINTAINERCLEANFILES += $(ibus_emoji_dialog_gir)
-+DISTCLEANFILES += $(ibus_emoji_dialog_gir)
-+
-+ibus-emoji-dialog-1.0.vapi: $(ibus_emoji_dialog_gir) IBusEmojiDialog-1.0.metadata
-+ibus_emoji_dialog_vapi = ibus-emoji-dialog-1.0.vapi
-+ibus_emoji_dialog_1_0_vapi_DEPS = gtk+-3.0 gio-2.0
-+ibus_emoji_dialog_1_0_vapi_METADATADIRS = $(srcdir)
-+ibus_emoji_dialog_1_0_vapi_FILES = IBusEmojiDialog-1.0.gir
-+VAPIGEN_VAPIS += $(ibus_emoji_dialog_vapi)
-+noinst_DATA += $(ibus_emoji_dialog_vapi)
-+EXTRA_DIST += $(ibus_emoji_dialog_vapi)
-+MAINTAINERCLEANFILES += $(ibus_emoji_dialog_vapi)
-+DISTCLEANFILES += $(ibus_emoji_dialog_vapi)
-+
-+endif
-+#end of HAVE_INTROSPECTION
-+endif
-+# end of ENABLE_EMOJI_DICT
- 
- -include $(top_srcdir)/git.mk
-diff --git a/ui/gtk3/ibus-emoji-dialog-1.0.deps b/bindings/vala/ibus-emoji-dialog-1.0.deps
-similarity index 100%
-rename from ui/gtk3/ibus-emoji-dialog-1.0.deps
-rename to bindings/vala/ibus-emoji-dialog-1.0.deps
-diff --git a/po/POTFILES.skip b/po/POTFILES.skip
-index 7190221d..10b88298 100644
---- a/po/POTFILES.skip
-+++ b/po/POTFILES.skip
-@@ -2,6 +2,11 @@
- # Please keep this file in alphabetical order.
- # Files under ui/gtk2/ are not shipped in the distribution, but kept
- # in the git repository for reference.
-+bindings/vala/candidatearea.c
-+bindings/vala/emojier.c
-+bindings/vala/iconwidget.c
-+bindings/vala/pango.c
-+bindings/vala/separator.c
- ibus/_config.py
- tools/main.c
- ui/gtk2/candidatepanel.py
-diff --git a/ui/gtk3/Makefile.am b/ui/gtk3/Makefile.am
-index c79641a5..786b80e6 100644
---- a/ui/gtk3/Makefile.am
-+++ b/ui/gtk3/Makefile.am
-@@ -81,10 +81,6 @@ AM_VALAFLAGS = \
- 	--target-glib="$(VALA_TARGET_GLIB_VERSION)" \
- 	$(NULL)
- 
--MAINTAINERCLEANFILES =
--DISTCLEANFILES =
--noinst_DATA =
--
- if ENABLE_LIBNOTIFY
- AM_CFLAGS += \
- 	@LIBNOTIFY_CFLAGS@ \
-@@ -158,9 +154,8 @@ man_seven_in_files = ibus-emoji.7.in
- EXTRA_DIST =                            \
-     $(emoji_headers)                    \
-     $(man_seven_in_files)               \
--    IBusEmojiDialog-1.0.metadata        \
-+    emojierapp.vala                     \
-     gtkpanel.xml.in                     \
--    ibus-emoji-dialog-1.0.deps          \
-     notification-item.xml               \
-     notification-watcher.xml            \
-     $(NULL)
-@@ -168,98 +163,40 @@ EXTRA_DIST =                            \
- if ENABLE_EMOJI_DICT
- AM_VALAFLAGS += --define=EMOJI_DICT
- 
--libibus_emoji_dialog = libibus-emoji-dialog-1.0.la
--
--noinst_LTLIBRARIES = $(libibus_emoji_dialog)
--
--libibus_emoji_dialog_1_0_la_CFLAGS = $(AM_CFLAGS)
--libibus_emoji_dialog_1_0_la_LDFLAGS =   \
--    -no-undefined                       \
--    -export-symbols-regex "ibus_.*"     \
--    -version-info @LT_VERSION_INFO@     \
--    $(NULL)
--libibus_emoji_dialog_1_0_la_SOURCES =   \
--    candidatearea.vala                  \
--    emojier.vala                        \
--    iconwidget.vala                     \
--    pango.vala                          \
--    separator.vala                      \
--    $(NULL)
--
- libexec_PROGRAMS += ibus-ui-emojier
- 
--ibus_ui_emojier_SOURCES =                       \
--    $(libibus_emoji_dialog_1_0_la_SOURCES)      \
-+ibus_ui_emojier_VALASOURCES =                   \
-     emojierapp.vala                             \
-+    candidatearea.vala                          \
-+    emojier.vala                                \
-+    iconwidget.vala                             \
-+    pango.vala                                  \
-+    separator.vala                              \
-+    $(NULL)
-+ibus_ui_emojier_SOURCES =                       \
-+    $(ibus_ui_emojier_VALASOURCES:.vala=.c)     \
-     $(NULL)
- 
- ibus_ui_emojier_LDADD =                         \
-     $(AM_LDADD)                                 \
-     $(NULL)
- 
---include $(INTROSPECTION_MAKEFILE)
--INTROSPECTION_SCANNER_ARGS =
--INTROSPECTION_COMPILER_ARGS =      \
--    --includedir=$(srcdir)         \
--    --includedir=.                 \
--    --includedir=$(top_srcdir)/src \
--    $(NULL)
--
--if HAVE_INTROSPECTION
--introspection_sources =                \
--    $(emoji_headers)                   \
--    $(NULL)
--IBusEmojiDialog-1.0.gir: $(libibus_emoji_dialog) Makefile
--IBusEmojiDialog_1_0_gir_SCANNERFLAGS = \
--    --pkg-export=ibus-1.0              \
--    --pkg=gtk+-3.0                     \
--    $(IBUS_GIR_SCANNERFLAGS)           \
-+ibus_ui_emojier_VALAFLAGS =                     \
-+    $(AM_VALAFLAGS)                             \
-     $(NULL)
--IBusEmojiDialog-1.0.gir: $(libibus_emoji_dialog) Makefile
--IBusEmojiDialog_1_0_gir_INCLUDES = Gtk-3.0 GLib-2.0 GObject-2.0 Gio-2.0
--IBusEmojiDialog_1_0_gir_LIBS = $(libibus_emoji_dialog) $(libibus)
--IBusEmojiDialog_1_0_gir_FILES =                      \
--    $(addprefix $(srcdir)/,$(introspection_sources)) \
--    $(NULL)
--IBusEmojiDialog_1_0_gir_CFLAGS =       \
--    -DIBUS_COMPILATION                 \
--    -I$(srcdir)                        \
--    -I$(builddir)                      \
--    -I$(top_srcdir)/src                \
--    $(NULL)
--INTROSPECTION_GIRS = IBusEmojiDialog-1.0.gir
--
--girdir = $(datadir)/gir-1.0
--noinst_DATA += $(INTROSPECTION_GIRS)
--CLEANFILES += $(INTROSPECTION_GIRS)
- 
--typelibsdir = $(libdir)/girepository-1.0
--noinst_DATA += $(INTROSPECTION_GIRS:.gir=.typelib)
--CLEANFILES += $(INTROSPECTION_GIRS:.gir=.typelib)
--
--
--if ENABLE_VAPIGEN
---include $(VAPIGEN_MAKEFILE)
--
--ibus-emoji-dialog-1.0.vapi: $(INTROSPECTION_GIRS) IBusEmojiDialog-1.0.metadata
--
--VAPIGEN_VAPIS = ibus-emoji-dialog-1.0.vapi
--
--ibus_emoji_dialog_1_0_vapi_DEPS = gtk+-3.0 gio-2.0
--ibus_emoji_dialog_1_0_vapi_METADATADIRS = $(srcdir)
--ibus_emoji_dialog_1_0_vapi_FILES = $(INTROSPECTION_GIRS)
--
--vapidir = $(datadir)/vala/vapi
--noinst_DATA += $(VAPIGEN_VAPIS) $(VAPIGEN_VAPIS:.vapi=.deps)
--
--MAINTAINERCLEANFILES += $(VAPIGEN_VAPIS)
--DISTCLEANFILES += $(VAPIGEN_VAPIS)
--EXTRA_DIST += $(VAPIGEN_VAPIS)
--
--# end of ENABLE_VAPIGEN
--endif
--# end of HAVE_INTROSPECTION
--endif
-+# This line and foo_VALASOURCES line can delete the duplicated entries
-+# of emojier.c: emojier.vala
-+emojierapp.c: $(ibus_ui_emojier_VALASOURCES)
-+	$(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) \
-+$(VALAFLAGS) -C $(ibus_ui_emojier_VALASOURCES)
-+	$(NULL)
-+# make dist creates .c files in a different srcdir
-+emojierapp.o: $(srcdir)/emojierapp.c
-+	$(AM_V_CC)source='$<' object='$@' libtool=no \
-+	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
-+	$(AM_V_CC_no)$(COMPILE) -c -o $@ $<
-+	$(NULL)
- 
- man_seven_files = $(man_seven_in_files:.7.in=.7)
- man_seven_DATA =$(man_seven_files:.7=.7.gz)
-@@ -276,7 +213,7 @@ CLEANFILES += \
-     $(man_seven_files) \
-     $(NULL)
- 
--# end of ENABLE_EMOJI_DICT
- endif
-+# end of ENABLE_EMOJI_DICT
- 
- -include $(top_srcdir)/git.mk
-diff --git a/ui/gtk3/emojier.vala b/ui/gtk3/emojier.vala
-index 9df59ac4..36ab4bab 100644
---- a/ui/gtk3/emojier.vala
-+++ b/ui/gtk3/emojier.vala
-@@ -1139,6 +1139,7 @@ class IBusEmojier : Gtk.ApplicationWindow {
-                     m_category_active_index = (int)list.length();
-         }
-         Gtk.Adjustment adjustment = m_list_box.get_adjustment();
-+        m_scrolled_window.set_hadjustment(new Gtk.Adjustment(0, 0, 0, 0, 0, 0));
-         m_scrolled_window.set_vadjustment(adjustment);
-         show_category_list();
-     }
-@@ -1156,7 +1157,7 @@ class IBusEmojier : Gtk.ApplicationWindow {
-             else if (keyval == Gdk.Key.Right)
-                 m_lookup_table.cursor_down();
-             show_candidate_panel();
--        } else if (m_entry.get_text().len() > 0) {
-+        } else if (m_entry.get_text().length > 0) {
-             int step = 0;
-             if (keyval == Gdk.Key.Left)
-                 step = -1;
-@@ -1211,7 +1212,7 @@ class IBusEmojier : Gtk.ApplicationWindow {
-             show_candidate_panel();
-             return true;
-         }
--        if (m_entry.get_text().len() > 0) {
-+        if (m_entry.get_text().length > 0) {
-             int step = 0;
-             if (keyval == Gdk.Key.Home)
-                 step = -1;
-@@ -1410,7 +1411,7 @@ class IBusEmojier : Gtk.ApplicationWindow {
-             key_press_enter();
-             return true;
-         case Gdk.Key.BackSpace:
--            if (m_entry.get_text().len() > 0) {
-+            if (m_entry.get_text().length > 0) {
-                 if ((modifiers & Gdk.ModifierType.CONTROL_MASK) != 0) {
-                     GLib.Signal.emit_by_name(m_entry, "delete-from-cursor",
-                                              Gtk.DeleteType.WORD_ENDS, -1);
-@@ -1422,7 +1423,7 @@ class IBusEmojier : Gtk.ApplicationWindow {
-             break;
-         case Gdk.Key.Delete:
-         case Gdk.Key.KP_Delete:
--            if (m_entry.get_text().len() > 0) {
-+            if (m_entry.get_text().length > 0) {
-                 if ((modifiers & Gdk.ModifierType.CONTROL_MASK) != 0) {
-                     GLib.Signal.emit_by_name(m_entry, "delete-from-cursor",
-                                              Gtk.DeleteType.WORD_ENDS, 1);
-@@ -1436,7 +1437,7 @@ class IBusEmojier : Gtk.ApplicationWindow {
-         case Gdk.Key.space:
-         case Gdk.Key.KP_Space:
-             if ((modifiers & Gdk.ModifierType.SHIFT_MASK) != 0) {
--                if (m_entry.get_text().len() > 0)
-+                if (m_entry.get_text().length > 0)
-                     entry_enter_keyval(keyval);
-             } else if (m_candidate_panel_is_visible) {
-                 enter_notify_disable_with_timer();
-@@ -1512,7 +1513,7 @@ class IBusEmojier : Gtk.ApplicationWindow {
-                     return true;
-                 break;
-             case Gdk.Key.u:
--                if (m_entry.get_text().len() > 0) {
-+                if (m_entry.get_text().length > 0) {
-                     GLib.Signal.emit_by_name(m_entry,
-                                              "delete-from-cursor",
-                                              Gtk.DeleteType.PARAGRAPH_ENDS,
-@@ -1521,13 +1522,13 @@ class IBusEmojier : Gtk.ApplicationWindow {
-                 }
-                 break;
-             case Gdk.Key.a:
--                if (m_entry.get_text().len() > 0) {
-+                if (m_entry.get_text().length > 0) {
-                     m_entry.select_region(0, -1);
-                     return true;
-                 }
-                 break;
-             case Gdk.Key.x:
--                if (m_entry.get_text().len() > 0) {
-+                if (m_entry.get_text().length > 0) {
-                     GLib.Signal.emit_by_name(m_entry, "cut-clipboard");
-                     return true;
-                 }
-@@ -1544,7 +1545,7 @@ class IBusEmojier : Gtk.ApplicationWindow {
-                         clipboard.store();
-                         return true;
-                     }
--                } else if (m_entry.get_text().len() > 0) {
-+                } else if (m_entry.get_text().length > 0) {
-                     GLib.Signal.emit_by_name(m_entry, "copy-clipboard");
-                     return true;
-                 }
-diff --git a/ui/gtk3/ibusemojidialog.h b/ui/gtk3/ibusemojidialog.h
-index 24d195c8..ed8886a8 100644
---- a/ui/gtk3/ibusemojidialog.h
-+++ b/ui/gtk3/ibusemojidialog.h
-@@ -170,5 +170,31 @@ void          ibus_emojier_set_favorites          (gchar**      favorites,
-                                                    favorite_annotations,
-                                                    int
-                                                    favorite_annotations_length);
-+
-+/**
-+ * ibus_emojier_set_partial_match:
-+ * @has_partial_match: Enable the partial match if %TRUE. Otherwise if %FALSE.
-+ *
-+ * Set partial match for emoji annotations.
-+ */
-+void          ibus_emojier_set_partial_match      (gboolean  has_partial_match);
-+
-+/**
-+ * ibus_emojier_set_partial_match_length:
-+ * @length: minimum lenght to match partially.
-+ *
-+ * Set the minimum lenght to match partially.
-+ */
-+void          ibus_emojier_set_partial_match_length
-+                                                  (gint         length);
-+
-+/**
-+ * ibus_emojier_set_partial_match_condition:
-+ * @condition: condition id between 0 and 2.
-+ *
-+ * Set the partial match condition with the integer.
-+ */
-+void          ibus_emojier_set_partial_match_condition
-+                                                  (gint         condition);
- G_END_DECLS
- #endif
--- 
-2.13.4
-
-From d788918b635275d0247e68f26f9c840100bca366 Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Wed, 6 Sep 2017 12:17:30 +0900
-Subject: [PATCH 09/14] ui/gtk3: Switcher should ignore mouse until it moves
-
-BUG=https://github.com/ibus/ibus/issues/1929
-
-Review URL: https://codereview.appspot.com/329100043
----
- ui/gtk3/switcher.vala | 28 +++++++++++++++++++++++++++-
- 1 file changed, 27 insertions(+), 1 deletion(-)
-
-diff --git a/ui/gtk3/switcher.vala b/ui/gtk3/switcher.vala
-index cf187555..269a68d4 100644
---- a/ui/gtk3/switcher.vala
-+++ b/ui/gtk3/switcher.vala
-@@ -91,6 +91,9 @@ class Switcher : Gtk.Window {
-     private uint m_popup_delay_time_id = 0;
-     private int m_root_x;
-     private int m_root_y;
-+    private double m_mouse_init_x;
-+    private double m_mouse_init_y;
-+    private bool   m_mouse_moved;
-     private GLib.HashTable<string, string> m_xkb_languages =
-             new GLib.HashTable<string, string>(GLib.str_hash,
-                                                GLib.str_equal);
-@@ -221,6 +224,11 @@ class Switcher : Gtk.Window {
-                               Gdk.CURRENT_TIME);
-         if (status != Gdk.GrabStatus.SUCCESS)
-             warning("Grab pointer failed! status = %d", status);
-+        // Probably we can delete m_popup_delay_time in 1.6
-+        pointer.get_position_double(null,
-+                                    out m_mouse_init_x,
-+                                    out m_mouse_init_y);
-+        m_mouse_moved = false;
- 
- 
-         m_loop = new GLib.MainLoop();
-@@ -263,12 +271,30 @@ class Switcher : Gtk.Window {
-             var button = new IBusEngineButton(engine, this);
-             var longname = engine.get_longname();
-             button.set_relief(Gtk.ReliefStyle.NONE);
-+            button.add_events(Gdk.EventMask.POINTER_MOTION_MASK);
-             button.show();
- 
-             button.enter_notify_event.connect((e) => {
-+                // avoid gtk_button_update_state()
-+                return true;
-+            });
-+            button.motion_notify_event.connect((e) => {
-+#if VALA_0_24
-+                Gdk.EventMotion pe = e;
-+#else
-+                Gdk.EventMotion *pe = &e;
-+#endif
-+                if (m_selected_engine == index)
-+                    return false;
-+                if (!m_mouse_moved &&
-+                    m_mouse_init_x == pe.x_root &&
-+                    m_mouse_init_y == pe.y_root) {
-+                    return false;
-+                }
-+                m_mouse_moved = true;
-                 button.grab_focus();
-                 m_selected_engine = index;
--                return true;
-+                return false;
-             });
- 
-             button.button_press_event.connect((e) => {
--- 
-2.13.4
-
-From bbfb3d738b9d61d1eb0658a9ce56e3cd8c111ac4 Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Wed, 6 Sep 2017 14:08:40 +0900
-Subject: [PATCH 10/14] client/gtk2: Do not send key events to
- GtkIMContextSimple
-
-GtkIMContextSimple binds Ctrl-Shift-u but IBus clients do not now.
-
-BUG=https://github.com/ibus/ibus/issues/1889
-R=Shawn.P.Huang@gmail.com
-
-Review URL: https://codereview.appspot.com/327290043
----
- client/gtk2/ibusimcontext.c | 41 +++++++++++++++++++++++++++++++++++++++--
- src/ibusenginesimple.c      | 23 ++---------------------
- src/ibusenginesimple.h      | 24 ++++++++++++++++++++++--
- 3 files changed, 63 insertions(+), 25 deletions(-)
-
-diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c
-index b4ca8828..3ea46951 100644
---- a/client/gtk2/ibusimcontext.c
-+++ b/client/gtk2/ibusimcontext.c
-@@ -2,7 +2,8 @@
- /* vim:set et sts=4: */
- /* ibus - The Input Bus
-  * Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
-- * Copyright (C) 2008-2013 Red Hat, Inc.
-+ * Copyright (C) 2015-2017 Takao Fujiwara <takao.fujiwara1@gmail.com>
-+ * Copyright (C) 2008-2017 Red Hat, Inc.
-  *
-  * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Lesser General Public
-@@ -247,6 +248,39 @@ _focus_out_cb (GtkWidget     *widget,
-     return FALSE;
- }
- 
-+static gboolean
-+ibus_im_context_commit_event (IBusIMContext *ibusimcontext,
-+                              GdkEventKey   *event)
-+{
-+    int i;
-+    GdkModifierType no_text_input_mask;
-+    gunichar ch;
-+
-+    if (event->type == GDK_KEY_RELEASE)
-+        return FALSE;
-+    /* Ignore modifier key presses */
-+    for (i = 0; i < G_N_ELEMENTS (IBUS_COMPOSE_IGNORE_KEYLIST); i++)
-+        if (event->keyval == IBUS_COMPOSE_IGNORE_KEYLIST[i])
-+            return FALSE;
-+    no_text_input_mask = gdk_keymap_get_modifier_mask (
-+            gdk_keymap_get_for_display (gdk_display_get_default ()),
-+            GDK_MODIFIER_INTENT_NO_TEXT_INPUT);
-+    if (event->state & no_text_input_mask ||
-+        event->keyval == GDK_KEY_Return ||
-+        event->keyval == GDK_KEY_ISO_Enter ||
-+        event->keyval == GDK_KEY_KP_Enter) {
-+        return FALSE;
-+    }
-+    ch = ibus_keyval_to_unicode (event->keyval);
-+    if (ch != 0 && !g_unichar_iscntrl (ch)) {
-+        IBusText *text = ibus_text_new_from_unichar (ch);
-+        g_signal_emit (ibusimcontext, _signal_commit_id, 0, text->text);
-+        g_object_unref (text);
-+        return TRUE;
-+    }
-+   return FALSE;
-+}
-+
- static void
- _process_key_event_done (GObject      *object,
-                          GAsyncResult *res,
-@@ -797,8 +831,11 @@ ibus_im_context_filter_keypress (GtkIMContext *context,
-     if (event->state & IBUS_HANDLED_MASK)
-         return TRUE;
- 
-+    /* Do not call gtk_im_context_filter_keypress() because
-+     * gtk_im_context_simple_filter_keypress() binds Ctrl-Shift-u
-+     */
-     if (event->state & IBUS_IGNORED_MASK)
--        return gtk_im_context_filter_keypress (ibusimcontext->slave, event);
-+        return ibus_im_context_commit_event (ibusimcontext, event);
- 
-     /* XXX it is a workaround for some applications do not set client
-      * window. */
-diff --git a/src/ibusenginesimple.c b/src/ibusenginesimple.c
-index cddd932c..63785223 100644
---- a/src/ibusenginesimple.c
-+++ b/src/ibusenginesimple.c
-@@ -81,25 +81,6 @@ const IBusComposeTableCompact ibus_compose_table_compact = {
- 
- static GSList *global_tables;
- 
--static const guint16 ibus_compose_ignore[] = {
--    IBUS_KEY_Shift_L,
--    IBUS_KEY_Shift_R,
--    IBUS_KEY_Control_L,
--    IBUS_KEY_Control_R,
--    IBUS_KEY_Caps_Lock,
--    IBUS_KEY_Shift_Lock,
--    IBUS_KEY_Meta_L,
--    IBUS_KEY_Meta_R,
--    IBUS_KEY_Alt_L,
--    IBUS_KEY_Alt_R,
--    IBUS_KEY_Super_L,
--    IBUS_KEY_Super_R,
--    IBUS_KEY_Hyper_L,
--    IBUS_KEY_Hyper_R,
--    IBUS_KEY_Mode_switch,
--    IBUS_KEY_ISO_Level3_Shift
--};
--
- /* functions prototype */
- static void     ibus_engine_simple_destroy      (IBusEngineSimple   *simple);
- static void     ibus_engine_simple_reset        (IBusEngine         *engine);
-@@ -1045,8 +1026,8 @@ ibus_engine_simple_process_key_event (IBusEngine *engine,
-     }
- 
-     /* Ignore modifier key presses */
--    for (i = 0; i < G_N_ELEMENTS (ibus_compose_ignore); i++)
--        if (keyval == ibus_compose_ignore[i])
-+    for (i = 0; i < G_N_ELEMENTS (IBUS_COMPOSE_IGNORE_KEYLIST); i++)
-+        if (keyval == IBUS_COMPOSE_IGNORE_KEYLIST[i])
-             return FALSE;
- 
-     if ((priv->in_hex_sequence || priv->in_emoji_sequence)
-diff --git a/src/ibusenginesimple.h b/src/ibusenginesimple.h
-index 8712659c..a5ef34fb 100644
---- a/src/ibusenginesimple.h
-+++ b/src/ibusenginesimple.h
-@@ -2,8 +2,8 @@
- /* vim:set et sts=4: */
- /* ibus - The Input Bus
-  * Copyright (C) 2008-2015 Peng Huang <shawn.p.huang@gmail.com>
-- * Copyright (C) 2015-2016 Takao Fujiwara <takao.fujiwara1@gmail.com>
-- * Copyright (C) 2008-2016 Red Hat, Inc.
-+ * Copyright (C) 2015-2017 Takao Fujiwara <takao.fujiwara1@gmail.com>
-+ * Copyright (C) 2008-2017 Red Hat, Inc.
-  *
-  * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Lesser General Public
-@@ -40,6 +40,7 @@
-  */
- 
- #include "ibusengine.h"
-+#include "ibuskeysyms.h"
- 
- G_BEGIN_DECLS
- 
-@@ -94,6 +95,25 @@ struct _IBusEngineSimpleClass {
-     gpointer pdummy[8];
- };
- 
-+static const guint16 IBUS_COMPOSE_IGNORE_KEYLIST[] = {
-+    IBUS_KEY_Shift_L,
-+    IBUS_KEY_Shift_R,
-+    IBUS_KEY_Control_L,
-+    IBUS_KEY_Control_R,
-+    IBUS_KEY_Caps_Lock,
-+    IBUS_KEY_Shift_Lock,
-+    IBUS_KEY_Meta_L,
-+    IBUS_KEY_Meta_R,
-+    IBUS_KEY_Alt_L,
-+    IBUS_KEY_Alt_R,
-+    IBUS_KEY_Super_L,
-+    IBUS_KEY_Super_R,
-+    IBUS_KEY_Hyper_L,
-+    IBUS_KEY_Hyper_R,
-+    IBUS_KEY_Mode_switch,
-+    IBUS_KEY_ISO_Level3_Shift
-+};
-+
- GType   ibus_engine_simple_get_type       (void);
- 
- /**
--- 
-2.13.4
-
-From d784e04c38eeb069f9a8da8b30743f4463fa34c3 Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Thu, 7 Sep 2017 10:57:14 +0900
-Subject: [PATCH 11/14] client/gtk2: Fix a build failure with
- GDK_MODIFIER_INTENT_NO_TEXT_INPUT
-
-BUG=https://github.com/ibus/ibus/issues/1942
-
-Review URL: https://codereview.appspot.com/327300043
----
- client/gtk2/ibusimcontext.c | 12 ++++++++++++
- 1 file changed, 12 insertions(+)
-
-diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c
-index 3ea46951..a806382d 100644
---- a/client/gtk2/ibusimcontext.c
-+++ b/client/gtk2/ibusimcontext.c
-@@ -262,9 +262,21 @@ ibus_im_context_commit_event (IBusIMContext *ibusimcontext,
-     for (i = 0; i < G_N_ELEMENTS (IBUS_COMPOSE_IGNORE_KEYLIST); i++)
-         if (event->keyval == IBUS_COMPOSE_IGNORE_KEYLIST[i])
-             return FALSE;
-+#if GTK_CHECK_VERSION (3, 4, 0)
-     no_text_input_mask = gdk_keymap_get_modifier_mask (
-             gdk_keymap_get_for_display (gdk_display_get_default ()),
-             GDK_MODIFIER_INTENT_NO_TEXT_INPUT);
-+#else
-+#  ifndef GDK_WINDOWING_QUARTZ
-+#    define _IBUS_NO_TEXT_INPUT_MOD_MASK (GDK_MOD1_MASK | GDK_CONTROL_MASK)
-+#  else
-+#    define _IBUS_NO_TEXT_INPUT_MOD_MASK (GDK_MOD2_MASK | GDK_CONTROL_MASK)
-+#  endif
-+
-+    no_text_input_mask = _IBUS_NO_TEXT_INPUT_MOD_MASK;
-+
-+#  undef _IBUS_NO_TEXT_INPUT_MOD_MASK
-+#endif
-     if (event->state & no_text_input_mask ||
-         event->keyval == GDK_KEY_Return ||
-         event->keyval == GDK_KEY_ISO_Enter ||
--- 
-2.13.4
-
-From 0632cbbbb573749bbca96a416fde1490810e52d2 Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Wed, 13 Sep 2017 18:15:06 +0900
-Subject: [PATCH 13/14] ui/gtk3: Fix PropertyPanel position in workarea
-
-gdk_screen_get_monitor_workarea() no longer return the correct area
-from "_NET_WORKAREA" atom in GTK 3.22 and now use
-gdk_monitor_get_workarea() instead.
-
-Use gdk_seat_grab() instead of deprecated gdk_device_grab().
-
-Use gtk_menu_popup_at_rect() instead of deprecated gtk_menu_popup() and
-generate a new foreign GdkWindow with mouse cursor for the Qt Window.
-
-Also fixed some deprecated APIs.
-
-R=Shawn.P.Huang@gmail.com
-
-Review URL: https://codereview.appspot.com/330190043
----
- ui/gtk3/candidatepanel.vala    |  40 ++++++++-------
- ui/gtk3/emojier.vala           |  24 ++++++---
- ui/gtk3/handle.vala            |   7 +--
- ui/gtk3/indicator.vala         |  68 ++++++++++++++++++++++++--
- ui/gtk3/keybindingmanager.vala |   2 +-
- ui/gtk3/panel.vala             | 108 +++++++++++++++++++++++++++++++----------
- ui/gtk3/propertypanel.vala     |  21 +++++++-
- ui/gtk3/switcher.vala          |  84 +++++++++++++++++++++++---------
- 8 files changed, 270 insertions(+), 84 deletions(-)
-
-diff --git a/ui/gtk3/candidatepanel.vala b/ui/gtk3/candidatepanel.vala
-index 0e5e3bc2..ec2d3db4 100644
---- a/ui/gtk3/candidatepanel.vala
-+++ b/ui/gtk3/candidatepanel.vala
-@@ -3,7 +3,7 @@
-  * ibus - The Input Bus
-  *
-  * Copyright(c) 2011-2015 Peng Huang <shawn.p.huang@gmail.com>
-- * Copyright(c) 2015-2016 Takao Fujiwara <takao.fujiwara1@gmail.com>
-+ * Copyright(c) 2015-2017 Takao Fujiwara <takao.fujiwara1@gmail.com>
-  *
-  * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Lesser General Public
-@@ -292,6 +292,26 @@ public class CandidatePanel : Gtk.Box{
-             adjust_window_position_vertical();
-     }
- 
-+    private Gdk.Rectangle get_monitor_geometry() {
-+        Gdk.Rectangle monitor_area = { 0, };
-+
-+        // Use get_monitor_geometry() instead of get_monitor_area().
-+        // get_monitor_area() excludes docks, but the lookup window should be
-+        // shown over them.
-+#if VALA_0_34
-+        Gdk.Monitor monitor = Gdk.Display.get_default().get_monitor_at_point(
-+                m_cursor_location.x,
-+                m_cursor_location.y);
-+        monitor_area = monitor.get_geometry();
-+#else
-+        Gdk.Screen screen = Gdk.Screen.get_default();
-+        int monitor_num = screen.get_monitor_at_point(m_cursor_location.x,
-+                                                      m_cursor_location.y);
-+        screen.get_monitor_geometry(monitor_num, out monitor_area);
-+#endif
-+        return monitor_area;
-+    }
-+
-     private void adjust_window_position_horizontal() {
-         Gdk.Point cursor_right_bottom = {
-                 m_cursor_location.x + m_cursor_location.width,
-@@ -305,14 +325,7 @@ public class CandidatePanel : Gtk.Box{
-             cursor_right_bottom.y + allocation.height
-         };
- 
--        Gdk.Screen screen = Gdk.Screen.get_default();
--        int monitor_num = screen.get_monitor_at_point(m_cursor_location.x,
--                                                      m_cursor_location.y);
--        // Use get_monitor_geometry() instead of get_monitor_area().
--        // get_monitor_area() excludes docks, but the lookup window should be
--        // shown over them.
--        Gdk.Rectangle monitor_area;
--        screen.get_monitor_geometry(monitor_num, out monitor_area);
-+        Gdk.Rectangle monitor_area = get_monitor_geometry();
-         int monitor_right = monitor_area.x + monitor_area.width;
-         int monitor_bottom = monitor_area.y + monitor_area.height;
- 
-@@ -358,14 +371,7 @@ public class CandidatePanel : Gtk.Box{
-             m_cursor_location.y + allocation.height
-         };
- 
--        Gdk.Screen screen = Gdk.Screen.get_default();
--        int monitor_num = screen.get_monitor_at_point(m_cursor_location.x,
--                                                      m_cursor_location.y);
--        // Use get_monitor_geometry() instead of get_monitor_area().
--        // get_monitor_area() excludes docks, but the lookup window should be
--        // shown over them.
--        Gdk.Rectangle monitor_area;
--        screen.get_monitor_geometry(monitor_num, out monitor_area);
-+        Gdk.Rectangle monitor_area = get_monitor_geometry();
-         int monitor_right = monitor_area.x + monitor_area.width;
-         int monitor_bottom = monitor_area.y + monitor_area.height;
- 
-diff --git a/ui/gtk3/emojier.vala b/ui/gtk3/emojier.vala
-index 36ab4bab..9cd98140 100644
---- a/ui/gtk3/emojier.vala
-+++ b/ui/gtk3/emojier.vala
-@@ -575,7 +575,7 @@ class IBusEmojier : Gtk.ApplicationWindow {
-         if (lang == "en") {
-             bool has_variant = false;
-             foreach (unichar ch in EMOJI_VARIANT_LIST) {
--                if (emoji.chr(-1, ch) != null) {
-+                if (emoji.index_of_char(ch) >= 0) {
-                     has_variant = true;
-                     break;
-                 }
-@@ -782,15 +782,17 @@ class IBusEmojier : Gtk.ApplicationWindow {
-     private bool check_unicode_point() {
-         string annotation = m_entry.get_text();
-         m_unicode_point = null;
--        var buff = new GLib.StringBuilder();
-+        // Add "0x" because uint64.ascii_strtoull() is not accessible
-+        // and need to use uint64.parse()
-+        var buff = new GLib.StringBuilder("0x");
-         var retval = new GLib.StringBuilder();
-         for (int i = 0; i < annotation.char_count(); i++) {
-             unichar ch = annotation.get_char(i);
-             if (ch == 0)
-                 return false;
-             if (ch.isspace()) {
--                unichar code = (unichar)buff.str.to_ulong(null, 16);
--                buff.erase();
-+                unichar code = (unichar)uint64.parse(buff.str);
-+                buff.assign("0x");
-                 if (!code.validate())
-                     return false;
-                 retval.append(code.to_string());
-@@ -800,7 +802,7 @@ class IBusEmojier : Gtk.ApplicationWindow {
-                 return false;
-             buff.append_unichar(ch);
-         }
--        unichar code = (unichar)buff.str.to_ulong(null, 16);
-+        unichar code = (unichar)uint64.parse(buff.str);
-         if (!code.validate())
-             return false;
-         retval.append(code.to_string());
-@@ -834,7 +836,7 @@ class IBusEmojier : Gtk.ApplicationWindow {
-                         matched = true;
-                     break;
-                 case 2:
--                    if (key.str(annotation) != null)
-+                    if (key.index_of(annotation) >= 0)
-                         matched = true;
-                     break;
-                 default:
-@@ -1586,10 +1588,16 @@ class IBusEmojier : Gtk.ApplicationWindow {
-     public void present_centralize(Gdk.Event event) {
-         Gtk.Allocation allocation;
-         get_allocation(out allocation);
--        Gdk.Screen screen = Gdk.Screen.get_default();
--        int monitor_num = screen.get_monitor_at_window(get_window());
-         Gdk.Rectangle monitor_area;
-+#if VALA_0_34
-+        Gdk.Display display = Gdk.Display.get_default();
-+        Gdk.Monitor monitor = display.get_monitor_at_window(this.get_window());
-+        monitor_area = monitor.get_geometry();
-+#else
-+        Gdk.Screen screen = Gdk.Screen.get_default();
-+        int monitor_num = screen.get_monitor_at_window(this.get_window());
-         screen.get_monitor_geometry(monitor_num, out monitor_area);
-+#endif
-         int x = (monitor_area.x + monitor_area.width - allocation.width)/2;
-         int y = (monitor_area.y + monitor_area.height
-                  - allocation.height)/2;
-diff --git a/ui/gtk3/handle.vala b/ui/gtk3/handle.vala
-index bef5e8ba..fc9164a0 100644
---- a/ui/gtk3/handle.vala
-+++ b/ui/gtk3/handle.vala
-@@ -3,7 +3,7 @@
-  * ibus - The Input Bus
-  *
-  * Copyright(c) 2011-2016 Peng Huang <shawn.p.huang@gmail.com>
-- * Copyright(c) 2016 Takao Fujiwara <takao.fujiwara1@gmail.com>
-+ * Copyright(c) 2016-2017 Takao Fujiwara <takao.fujiwara1@gmail.com>
-  *
-  * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Lesser General Public
-@@ -59,7 +59,6 @@ class Handle : Gtk.EventBox {
- 
-     public override void realize() {
-         base.realize();
--        // get_window().set_cursor(new Gdk.Cursor(Gdk.CursorType.FLEUR));
-     }
- 
-     public override bool button_press_event(Gdk.EventButton event) {
-@@ -138,7 +137,9 @@ class Handle : Gtk.EventBox {
-         m_move_begined = false;
-         m_press_pos.x = 0;
-         m_press_pos.y = 0;
--        get_window().set_cursor(new Gdk.Cursor(Gdk.CursorType.LEFT_PTR));
-+        get_window().set_cursor(new Gdk.Cursor.for_display(
-+                   Gdk.Display.get_default(),
-+                   Gdk.CursorType.FLEUR));
-         move_end();
-         return true;
-     }
-diff --git a/ui/gtk3/indicator.vala b/ui/gtk3/indicator.vala
-index dac72b49..4d111a64 100644
---- a/ui/gtk3/indicator.vala
-+++ b/ui/gtk3/indicator.vala
-@@ -2,7 +2,7 @@
-  *
-  * ibus - The Input Bus
-  *
-- * Copyright(c) 2015 Takao Fujiwara <takao.fujiwara1@gmail.com>
-+ * Copyright(c) 2015-2017 Takao Fujiwara <takao.fujiwara1@gmail.com>
-  * Copyright(c) 2015 Red Hat, Inc.
-  *
-  * This library is free software; you can redistribute it and/or
-@@ -97,6 +97,7 @@ class Indicator : IBus.Service
-     private int m_context_menu_y;
-     private int m_activate_menu_x;
-     private int m_activate_menu_y;
-+    private Gdk.Window m_indicator_window;
- 
-     public Indicator(string id,
-                      GLib.DBusConnection connection,
-@@ -206,7 +207,8 @@ class Indicator : IBus.Service
-         GLib.Variant var_y = parameters.get_child_value(1);
-         m_context_menu_x = var_x.get_int32();
-         m_context_menu_y = var_y.get_int32();
--        context_menu(2, 0);
-+        Gdk.Window window = query_gdk_window();
-+        context_menu(m_context_menu_x, m_context_menu_y, window, 2, 0);
-     }
- 
-     private void _activate_menu_cb(GLib.DBusConnection       connection,
-@@ -216,7 +218,57 @@ class Indicator : IBus.Service
-         GLib.Variant var_y = parameters.get_child_value(1);
-         m_activate_menu_x = var_x.get_int32();
-         m_activate_menu_y = var_y.get_int32();
--        activate();
-+        Gdk.Window window = query_gdk_window();
-+        activate(m_activate_menu_x, m_activate_menu_y, window);
-+    }
-+
-+    private Gdk.Window? query_gdk_window() {
-+        if (m_indicator_window != null)
-+            return m_indicator_window;
-+
-+        Gdk.Display display = Gdk.Display.get_default();
-+        unowned X.Display xdisplay =
-+                (display as Gdk.X11.Display).get_xdisplay();
-+        X.Window current = xdisplay.default_root_window();
-+        X.Window parent = 0;
-+        X.Window child = 0;
-+        int root_x, root_y, win_x, win_y;
-+        uint mask = 0;
-+        root_x = root_y = win_x = win_y = 0;
-+        bool retval;
-+        // Need XSetErrorHandler for BadWindow?
-+        while ((retval = xdisplay.query_pointer(current,
-+                                      out parent, out child,
-+                                      out root_x, out root_y,
-+                                      out win_x, out win_y,
-+                                      out mask))) {
-+            if (child == 0)
-+                break;
-+            current = child;
-+        }
-+        if (!retval) {
-+            string format =
-+                    "XQueryPointer is failed: current: %x root: %x " +
-+                    "child: %x (%d, %d), (%d, %d), %u";
-+            string message = format.printf((uint)current,
-+                                           (uint)xdisplay.default_root_window(),
-+                                           (uint)child,
-+                                           root_x, root_y, win_x, win_y,
-+                                           mask);
-+            warning("XQueryPointer is failed: %s", message);
-+            return null;
-+        }
-+        if (current == xdisplay.default_root_window())
-+            warning("The query window is root window");
-+        m_indicator_window = Gdk.X11.Window.lookup_for_display(
-+                display as Gdk.X11.Display,
-+                current);
-+        if (m_indicator_window != null)
-+            return m_indicator_window;
-+        m_indicator_window = new Gdk.X11.Window.foreign_for_display(
-+                display as Gdk.X11.Display,
-+                current);
-+        return m_indicator_window;
-     }
- 
-     private GLib.Variant? _get_id(GLib.DBusConnection connection) {
-@@ -479,7 +531,13 @@ class Indicator : IBus.Service
-         push_in = false;
-     }
- 
--    public signal void context_menu(uint button, uint activate_time);
--    public signal void activate();
-+    public signal void context_menu(int        x,
-+                                    int        y,
-+                                    Gdk.Window window,
-+                                    uint       button,
-+                                    uint       activate_time);
-+    public signal void activate(int        x,
-+                                int        y,
-+                                Gdk.Window window);
-     public signal void registered_status_notifier_item();
- }
-diff --git a/ui/gtk3/keybindingmanager.vala b/ui/gtk3/keybindingmanager.vala
-index 49013b8d..c8b1e7f6 100644
---- a/ui/gtk3/keybindingmanager.vala
-+++ b/ui/gtk3/keybindingmanager.vala
-@@ -18,7 +18,7 @@ public class KeybindingManager : GLib.Object {
- 
-     private static KeybindingManager m_instance = null;
- 
--    public static const uint MODIFIER_FILTER =
-+    public const uint MODIFIER_FILTER =
-         Gdk.ModifierType.MODIFIER_MASK & ~(
-         Gdk.ModifierType.LOCK_MASK |  // Caps Lock
-         // Gdk.ModifierType.MOD1_MASK |  // Alt
-diff --git a/ui/gtk3/panel.vala b/ui/gtk3/panel.vala
-index bf43cbf9..629dadce 100644
---- a/ui/gtk3/panel.vala
-+++ b/ui/gtk3/panel.vala
-@@ -267,6 +267,27 @@ class Panel : IBus.PanelService {
-         });
-     }
- 
-+    private void popup_menu_at_area_window(Gtk.Menu              menu,
-+                                           Gdk.Rectangle         area,
-+                                           Gdk.Window?           window,
-+                                           Gtk.MenuPositionFunc? func) {
-+#if VALA_0_34
-+        Gdk.Gravity rect_anchor = Gdk.Gravity.SOUTH_WEST;
-+        Gdk.Gravity menu_anchor = Gdk.Gravity.NORTH_WEST;
-+
-+        // Gtk.Menu.popup() is now deprecated but
-+        // Gtk.Menu.popup_at_rect() requires a Gdk.Window and
-+        // Gtk.Menu.popup_at_rect() outputs a warning of
-+        // "no trigger event for menu popup"
-+        // for the foreigner QT window which is generated by
-+        // Gdk.X11.Window.foreign_for_display.
-+        // https://git.gnome.org/browse/gtk+/tree/gtk/gtkmenu.c?h=gtk-3-22#n2251
-+        menu.popup_at_rect(window, area, rect_anchor, menu_anchor, null);
-+#else
-+        menu.popup(null, null, func, 0, Gtk.get_current_event_time());
-+#endif
-+    }
-+
- #if INDICATOR
-     private bool is_kde() {
-         if (Environment.get_variable("XDG_CURRENT_DESKTOP") == "KDE")
-@@ -276,6 +297,19 @@ class Panel : IBus.PanelService {
-         return false;
-     }
- 
-+    private void popup_menu_at_pointer_window(Gtk.Menu              menu,
-+                                              int                   x,
-+                                              int                   y,
-+                                              Gdk.Window?           window,
-+                                              Gtk.MenuPositionFunc? func) {
-+        int win_x = 0;
-+        int win_y = 0;
-+        window.get_origin(out win_x, out win_y);
-+        Gdk.Rectangle area = { x - win_x, y - win_y, 1, 1 };
-+        // window is a bottom wide panel instead of status icon
-+        popup_menu_at_area_window(menu, area, window, func);
-+    }
-+
-     private void init_indicator() {
-         m_icon_type = IconType.INDICATOR;
-         GLib.Bus.get.begin(GLib.BusType.SESSION, null, (obj, res) => {
-@@ -290,21 +324,17 @@ class Panel : IBus.PanelService {
-                     m_indicator.set_status(Indicator.Status.ACTIVE);
-                     state_changed();
-                 });
--                m_indicator.context_menu.connect((b, t) => {
--                    Gtk.Menu menu = create_context_menu();
--                    menu.popup(null,
--                               null,
--                               m_indicator.position_context_menu,
--                               0,
--                               Gtk.get_current_event_time());
-+                m_indicator.context_menu.connect((x, y, w, b, t) => {
-+                    popup_menu_at_pointer_window(
-+                            create_context_menu(),
-+                            x, y, w,
-+                            m_indicator.position_context_menu);
-                 });
--                m_indicator.activate.connect(() => {
--                    Gtk.Menu menu = create_activate_menu();
--                    menu.popup(null,
--                               null,
--                               m_indicator.position_activate_menu,
--                               0,
--                               Gtk.get_current_event_time());
-+                m_indicator.activate.connect((x, y, w) => {
-+                    popup_menu_at_pointer_window(
-+                            create_activate_menu(),
-+                            x, y, w,
-+                            m_indicator.position_activate_menu);
-                 });
-             } catch (GLib.IOError e) {
-                 warning("Failed to get the session bus: %s", e.message);
-@@ -317,21 +347,47 @@ class Panel : IBus.PanelService {
-         m_status_icon = new Gtk.StatusIcon();
-         m_status_icon.set_name("ibus-ui-gtk");
-         m_status_icon.set_title(_("IBus Panel"));
-+
-+        // Gdk.Window.get_width() is needed for the menu position
-+        if (m_status_icon.get_size() > 0)
-+            init_status_icon_menu();
-+        else
-+            m_status_icon.notify["size"].connect(init_status_icon_menu);
-+    }
-+
-+    private void init_status_icon_menu() {
-+        Gdk.Rectangle area = { 0, 0, 0, 0 };
-+        Gdk.Window? window = null;
-+        Gtk.MenuPositionFunc? func = null;
-+#if VALA_0_34
-+        window = Gdk.X11.Window.lookup_for_display(
-+                Gdk.Display.get_default() as Gdk.X11.Display,
-+                m_status_icon.get_x11_window_id()) as Gdk.Window;
-+        if (window == null) {
-+            warning("StatusIcon does not have GdkWindow");
-+            return;
-+        }
-+        Gtk.Orientation orient;
-+        m_status_icon.get_geometry(null, out area, out orient);
-+        int win_x = 0;
-+        int win_y = 0;
-+        window.get_origin(out win_x, out win_y);
-+        // The (x, y) is converted by gdk_window_get_root_coords()
-+        // in gdk_window_impl_move_to_rect()
-+        area.x -= win_x;
-+        area.y -= win_y;
-+#else
-+        func = m_status_icon.position_menu;
-+#endif
-         m_status_icon.popup_menu.connect((b, t) => {
--                Gtk.Menu menu = create_context_menu();
--                menu.popup(null,
--                           null,
--                           m_status_icon.position_menu,
--                           0,
--                           Gtk.get_current_event_time());
-+                popup_menu_at_area_window(
-+                        create_context_menu(),
-+                        area, window, func);
-         });
-         m_status_icon.activate.connect(() => {
--                Gtk.Menu menu = create_activate_menu();
--                menu.popup(null,
--                           null,
--                           m_status_icon.position_menu,
--                           0,
--                           Gtk.get_current_event_time());
-+                popup_menu_at_area_window(
-+                        create_activate_menu(),
-+                        area, window, func);
-         });
-         m_status_icon.set_from_icon_name("ibus-keyboard");
-     }
-diff --git a/ui/gtk3/propertypanel.vala b/ui/gtk3/propertypanel.vala
-index dd4342ec..857f8e20 100644
---- a/ui/gtk3/propertypanel.vala
-+++ b/ui/gtk3/propertypanel.vala
-@@ -4,7 +4,7 @@
-  *
-  * Copyright(c) 2013-2016 Red Hat, Inc.
-  * Copyright(c) 2013-2015 Peng Huang <shawn.p.huang@gmail.com>
-- * Copyright(c) 2013-2016 Takao Fujiwara <takao.fujiwara1@gmail.com>
-+ * Copyright(c) 2013-2017 Takao Fujiwara <takao.fujiwara1@gmail.com>
-  *
-  * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Lesser General Public
-@@ -330,8 +330,16 @@ public class PropertyPanel : Gtk.Box {
-         Gtk.Allocation allocation;
-         m_toplevel.get_allocation(out allocation);
- 
-+        Gdk.Rectangle monitor_area;
-+#if VALA_0_34
-+        // gdk_screen_get_monitor_workarea() no longer return the correct
-+        // area from "_NET_WORKAREA" atom in GTK 3.22
-+        Gdk.Monitor monitor = Gdk.Display.get_default().get_monitor(0);
-+        monitor_area = monitor.get_workarea();
-+#else
-         Gdk.Screen screen = Gdk.Screen.get_default();
--        Gdk.Rectangle monitor_area = screen.get_monitor_workarea(0);
-+        monitor_area = screen.get_monitor_workarea(0);
-+#endif
-         int monitor_right = monitor_area.x + monitor_area.width;
-         int monitor_bottom = monitor_area.y + monitor_area.height;
-         int x, y;
-@@ -472,8 +480,15 @@ public class PropMenu : Gtk.Menu, IPropToolItem {
-     public new void popup(uint       button,
-                           uint32     activate_time,
-                           Gtk.Widget widget) {
-+#if VALA_0_34
-+        base.popup_at_widget(widget,
-+                             Gdk.Gravity.SOUTH_WEST,
-+                             Gdk.Gravity.NORTH_WEST,
-+                             null);
-+#else
-         m_parent_button = widget;
-         base.popup(null, null, menu_position, button, activate_time);
-+#endif
-     }
- 
-     public override void destroy() {
-@@ -532,6 +547,7 @@ public class PropMenu : Gtk.Menu, IPropToolItem {
-         }
-     }
- 
-+#if !VALA_0_34
-     private void menu_position(Gtk.Menu menu,
-                                out int  x,
-                                out int  y,
-@@ -580,6 +596,7 @@ public class PropMenu : Gtk.Menu, IPropToolItem {
- 
-         push_in = false;
-     }
-+#endif
- }
- 
- public class PropToolButton : Gtk.ToolButton, IPropToolItem {
-diff --git a/ui/gtk3/switcher.vala b/ui/gtk3/switcher.vala
-index 269a68d4..0ce742a1 100644
---- a/ui/gtk3/switcher.vala
-+++ b/ui/gtk3/switcher.vala
-@@ -157,6 +157,55 @@ class Switcher : Gtk.Window {
-         m_label.set_text(m_buttons[index].longname);
-         m_buttons[index].grab_focus();
- 
-+        // Avoid regressions.
-+        if (m_popup_delay_time > 0) {
-+            get_position(out m_root_x, out m_root_y);
-+            // Pull the window from the screen so that the window gets
-+            // the key press and release events but mouse does not select
-+            // an IME unexpectedly.
-+            move(-1000, -1000);
-+        }
-+
-+        show_all();
-+
-+        if (m_popup_delay_time > 0) {
-+            // Restore the window position after m_popup_delay_time
-+            m_popup_delay_time_id = GLib.Timeout.add(m_popup_delay_time,
-+                                                     () => {
-+                restore_window_position("timeout");
-+                return false;
-+            });
-+        }
-+
-+        Gdk.Device pointer;
-+#if VALA_0_34
-+        Gdk.Seat seat = event.get_seat();
-+        if (seat == null) {
-+            var display = get_display();
-+            seat = display.get_default_seat();
-+        }
-+        //keyboard = seat.get_keyboard();
-+        pointer = seat.get_pointer();
-+
-+        Gdk.GrabStatus status;
-+        // Grab all keyboard events
-+        status = seat.grab(get_window(),
-+                           Gdk.SeatCapabilities.KEYBOARD,
-+                           true,
-+                           null,
-+                           event,
-+                           null);
-+        if (status != Gdk.GrabStatus.SUCCESS)
-+            warning("Grab keyboard failed! status = %d", status);
-+        status = seat.grab(get_window(),
-+                           Gdk.SeatCapabilities.POINTER,
-+                           true,
-+                           null,
-+                           event,
-+                           null);
-+        if (status != Gdk.GrabStatus.SUCCESS)
-+            warning("Grab pointer failed! status = %d", status);
-+#else
-         Gdk.Device device = event.get_device();
-         if (device == null) {
-             var display = get_display();
-@@ -174,7 +223,6 @@ class Switcher : Gtk.Window {
-         }
- 
-         Gdk.Device keyboard;
--        Gdk.Device pointer;
-         if (device.get_source() == Gdk.InputSource.KEYBOARD) {
-             keyboard = device;
-             pointer = device.get_associated_device();
-@@ -183,26 +231,6 @@ class Switcher : Gtk.Window {
-             keyboard = device.get_associated_device();
-         }
- 
--        // Avoid regressions.
--        if (m_popup_delay_time > 0) {
--            get_position(out m_root_x, out m_root_y);
--            // Pull the window from the screen so that the window gets
--            // the key press and release events but mouse does not select
--            // an IME unexpectedly.
--            move(-1000, -1000);
--        }
--
--        show_all();
--
--        if (m_popup_delay_time > 0) {
--            // Restore the window position after m_popup_delay_time
--            m_popup_delay_time_id = GLib.Timeout.add(m_popup_delay_time,
--                                                     () => {
--                restore_window_position("timeout");
--                return false;
--            });
--        }
--
-         Gdk.GrabStatus status;
-         // Grab all keyboard events
-         status = keyboard.grab(get_window(),
-@@ -224,6 +252,8 @@ class Switcher : Gtk.Window {
-                               Gdk.CURRENT_TIME);
-         if (status != Gdk.GrabStatus.SUCCESS)
-             warning("Grab pointer failed! status = %d", status);
-+#endif
-+
-         // Probably we can delete m_popup_delay_time in 1.6
-         pointer.get_position_double(null,
-                                     out m_mouse_init_x,
-@@ -235,8 +265,12 @@ class Switcher : Gtk.Window {
-         m_loop.run();
-         m_loop = null;
- 
-+#if VALA_0_34
-+        seat.ungrab();
-+#else
-         keyboard.ungrab(Gdk.CURRENT_TIME);
-         pointer.ungrab(Gdk.CURRENT_TIME);
-+#endif
- 
-         hide();
-         // Make sure the switcher is hidden before returning from this function.
-@@ -319,13 +353,19 @@ class Switcher : Gtk.Window {
-         m_label.set_ellipsize(Pango.EllipsizeMode.END);
- 
-         Gdk.Display display = Gdk.Display.get_default();
-+        int screen_width = 0;
-+#if VALA_0_34
-+        Gdk.Monitor monitor = display.get_monitor_at_window(this.get_window());
-+        Gdk.Rectangle area = monitor.get_geometry();
-+        screen_width = area.width;
-+#else
-         Gdk.Screen screen = (display != null) ?
-                 display.get_default_screen() : null;
--        int screen_width = 0;
- 
-         if (screen != null) {
-             screen_width = screen.get_width();
-         }
-+#endif
- 
-         if (screen_width > 0 && max_label_width > (screen_width / 4)) {
-             max_label_width = screen_width / 4;
--- 
-2.13.4
-
-From 4a541639f50f05bf01b1b84792a7f4039b88c296 Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Fri, 15 Sep 2017 17:49:57 +0900
-Subject: [PATCH] ui/gtk3: Fix to enable menu button on PropertyPanel
-
-Review URL: https://codereview.appspot.com/330720043
----
- ui/gtk3/propertypanel.vala | 17 +++++++++++++++++
- 1 file changed, 17 insertions(+)
-
-diff --git a/ui/gtk3/propertypanel.vala b/ui/gtk3/propertypanel.vala
-index 857f8e20..f5d9cff7 100644
---- a/ui/gtk3/propertypanel.vala
-+++ b/ui/gtk3/propertypanel.vala
-@@ -84,6 +84,23 @@ public class PropertyPanel : Gtk.Box {
-     public void set_properties(IBus.PropList props) {
-         debug("set_properties()\n");
- 
-+        // When click PropMenuToolButton, the focus is changed and
-+        // set_properties() is called here while the menu button is active.
-+        // Ignore that case here not to remove items.
-+        bool has_active = false;
-+        foreach (var item in m_items) {
-+            Type type = item.get_type();
-+            if (type == typeof(PropMenuToolButton) ||
-+                type == typeof(PropToggleToolButton)) {
-+                if ((item as Gtk.ToggleToolButton).get_active()) {
-+                    has_active = true;
-+                    break;
-+                }
-+            }
-+        }
-+        if (has_active)
-+            return;
-+
-         foreach (var item in m_items)
-             remove((item as Gtk.Widget));
-         m_items = {};
--- 
-2.13.4
-
-From f6a0100fcd123dc287b606d722b4d83a7d6b1ea7 Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Thu, 21 Sep 2017 05:27:19 +0900
-Subject: [PATCH] ui/gtk3: Unset GDK_CORE_DEVICE_EVENTS
-
-Plasma deskop sets this variable and prevents Super+space,
-and Ctrl-Shift-e when ibus-ui-gtk3 runs after the
-desktop is launched.
-Also fixed a SEGV in display.get_monitor_at_window()
-Regression from rhbz#226465
----
- ui/gtk3/application.vala | 6 ++++++
- ui/gtk3/switcher.vala    | 3 ++-
- 2 files changed, 8 insertions(+), 1 deletion(-)
-
-diff --git a/ui/gtk3/application.vala b/ui/gtk3/application.vala
-index fa802721..770a32f2 100644
---- a/ui/gtk3/application.vala
-+++ b/ui/gtk3/application.vala
-@@ -100,6 +100,12 @@ class Application {
-     }
- 
-     public static void main(string[] argv) {
-+        // https://bugzilla.redhat.com/show_bug.cgi?id=1226465#c20
-+        // In /etc/xdg/plasma-workspace/env/gtk3_scrolling.sh
-+        // Plasma deskop sets this variable and prevents Super+space,
-+        // and Ctrl-Shift-e when ibus-ui-gtk3 runs after the
-+        // desktop is launched.
-+        GLib.Environment.unset_variable("GDK_CORE_DEVICE_EVENTS");
-         // for Gdk.X11.get_default_xdisplay()
-         Gdk.set_allowed_backends("x11");
- 
-diff --git a/ui/gtk3/switcher.vala b/ui/gtk3/switcher.vala
-index 0ce742a1..2a48c1f1 100644
---- a/ui/gtk3/switcher.vala
-+++ b/ui/gtk3/switcher.vala
-@@ -355,7 +355,8 @@ class Switcher : Gtk.Window {
-         Gdk.Display display = Gdk.Display.get_default();
-         int screen_width = 0;
- #if VALA_0_34
--        Gdk.Monitor monitor = display.get_monitor_at_window(this.get_window());
-+        // display.get_monitor_at_window() is null because of unrealized window
-+        Gdk.Monitor monitor = display.get_primary_monitor();
-         Gdk.Rectangle area = monitor.get_geometry();
-         screen_width = area.width;
- #else
--- 
-2.13.4
-

                 reply	other threads:[~2026-05-31  2:06 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=178019319906.1.2017495390622560238.rpms-ibus-4950bbe7d42c@fedoraproject.org \
    --to=tfujiwar@redhat.com \
    --cc=git-commits@fedoraproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox