Blame SOURCES/ibus-1612432-commit-with-mouse.patch

186ff6
From 8ab0b603ba1cd8701583aee46c712898d52005f1 Mon Sep 17 00:00:00 2001
186ff6
From: fujiwarat <takao.fujiwara1@gmail.com>
186ff6
Date: Wed, 23 May 2018 19:20:10 +0900
186ff6
Subject: [PATCH] bus: Fix a SEGV in bus_input_context_emit_signal
186ff6
186ff6
IBus engines can call 'RequireSurroundingText' for a fake input context
186ff6
if there is no input focus.
186ff6
---
186ff6
 bus/inputcontext.c | 4 +++-
186ff6
 1 file changed, 3 insertions(+), 1 deletion(-)
186ff6
186ff6
diff --git a/bus/inputcontext.c b/bus/inputcontext.c
186ff6
index a957d107..dfb98c36 100644
186ff6
--- a/bus/inputcontext.c
186ff6
+++ b/bus/inputcontext.c
186ff6
@@ -716,7 +716,9 @@ bus_input_context_emit_signal (BusInputContext *context,
186ff6
                                GError         **error)
186ff6
 {
186ff6
     if (context->connection == NULL) {
186ff6
-        g_variant_unref (parameters);
186ff6
+        /* fake context has no connections. */
186ff6
+        if (parameters)
186ff6
+            g_variant_unref (parameters);
186ff6
         return TRUE;
186ff6
     }
186ff6
 
186ff6
-- 
186ff6
2.20.1
186ff6
186ff6
From a40631e166137c9042a68c2d76844e7afc53d388 Mon Sep 17 00:00:00 2001
186ff6
From: fujiwarat <takao.fujiwara1@gmail.com>
186ff6
Date: Fri, 9 Nov 2018 14:49:44 +0900
186ff6
Subject: [PATCH 1/4] Detect mouse click to commit Hangul preedit
186ff6
186ff6
If preedit text is not committed with the mouse click, preedit text
186ff6
is moved to the new cursor position in Hangul typing.
186ff6
Since set_cursor_location() is received before the reset() signal is
186ff6
sent to ibus-daemon and commit_text() signal is received from
186ff6
ibus-daemon, UpdatePreeditTextWithMode D-Bus method is newly added
186ff6
and now ibus clients commit the preedit.
186ff6
186ff6
BUG=https://github.com/ibus/ibus/issues/1980
186ff6
---
186ff6
 bus/ibusimpl.c              |  11 ++++
186ff6
 bus/inputcontext.c          | 108 ++++++++++++++++++++++++-------
186ff6
 bus/inputcontext.h          |  19 +++++-
186ff6
 client/gtk2/ibusimcontext.c |  95 +++++++++++++++++++++++++---
186ff6
 src/ibusinputcontext.c      | 122 ++++++++++++++++++++++++++++++++----
186ff6
 src/ibusinputcontext.h      |  27 +++++++-
186ff6
 6 files changed, 338 insertions(+), 44 deletions(-)
186ff6
186ff6
diff --git a/bus/ibusimpl.c b/bus/ibusimpl.c
186ff6
index 80f3acfb..bbbb5770 100644
186ff6
--- a/bus/ibusimpl.c
186ff6
+++ b/bus/ibusimpl.c
186ff6
@@ -629,6 +629,17 @@ bus_ibus_impl_set_focused_context (BusIBusImpl     *ibus,
186ff6
             engine = bus_input_context_get_engine (ibus->focused_context);
186ff6
             if (engine) {
186ff6
                 g_object_ref (engine);
186ff6
+                /* _ic_focus_in() can be called before _ic_focus_out() is
186ff6
+                 * called under the async processes of two ibus clients.
186ff6
+                 * E.g. gedit is a little slower v.s. a simple GtkTextView
186ff6
+                 * application is the fastest when you click a Hangul
186ff6
+                 * preedit text between the applications.
186ff6
+                 * preedit will be committed with focus-out in the ibus client
186ff6
+                 * likes ibus-im.so
186ff6
+                 * so do not commit preedit here in focus-in event.
186ff6
+                 */
186ff6
+                bus_input_context_clear_preedit_text (ibus->focused_context,
186ff6
+                                                      FALSE);
186ff6
                 bus_input_context_set_engine (ibus->focused_context, NULL);
186ff6
             }
186ff6
         }
186ff6
diff --git a/bus/inputcontext.c b/bus/inputcontext.c
186ff6
index 4f98b849..1b8e7adb 100644
186ff6
--- a/bus/inputcontext.c
186ff6
+++ b/bus/inputcontext.c
186ff6
@@ -73,6 +73,7 @@ struct _BusInputContext {
186ff6
     guint     preedit_cursor_pos;
186ff6
     gboolean  preedit_visible;
186ff6
     guint     preedit_mode;
186ff6
+    gboolean  client_commit_preedit;
186ff6
 
186ff6
     /* auxiliary text */
186ff6
     IBusText *auxiliary_text;
186ff6
@@ -216,6 +217,9 @@ static IBusPropList    *props_empty = NU
186ff6
 static const gchar introspection_xml[] =
186ff6
     "<node>"
186ff6
     "  <interface name='org.freedesktop.IBus.InputContext'>"
186ff6
+    /* properties */
186ff6
+    "    <property name='ContentType' type='(uu)' access='write' />"
186ff6
+    "    <property name='ClientCommitPreedit' type='(b)' access='write' />\n"
186ff6
     /* methods */
186ff6
     "    <method name='ProcessKeyEvent'>"
186ff6
     "      <arg direction='in'  type='u' name='keyval' />"
186ff6
@@ -277,6 +281,12 @@ static const gchar introspection_xml[] =
186ff6
     "      <arg type='u' name='cursor_pos' />"
186ff6
     "      <arg type='b' name='visible' />"
186ff6
     "    </signal>"
186ff6
+    "    <signal name='UpdatePreeditTextWithMode'>"
186ff6
+    "      <arg type='v' name='text' />"
186ff6
+    "      <arg type='u' name='cursor_pos' />"
186ff6
+    "      <arg type='b' name='visible' />"
186ff6
+    "      <arg type='u' name='mode' />"
186ff6
+    "    </signal>"
186ff6
     "    <signal name='ShowPreeditText'/>"
186ff6
     "    <signal name='HidePreeditText'/>"
186ff6
     "    <signal name='UpdateAuxiliaryText'>"
186ff6
@@ -301,9 +311,6 @@ static const gchar introspection_xml[] =
186ff6
     "    <signal name='UpdateProperty'>"
186ff6
     "      <arg type='v' name='prop' />"
186ff6
     "    </signal>"
186ff6
-
186ff6
-    /* properties */
186ff6
-    "    <property name='ContentType' type='(uu)' access='write' />"
186ff6
     "  </interface>"
186ff6
     "</node>";
186ff6
 
186ff6
@@ -981,6 +988,12 @@ _ic_reset (BusInputContext       *contex
186ff6
            GDBusMethodInvocation *invocation)
186ff6
 {
186ff6
     if (context->engine) {
186ff6
+        if (context->preedit_mode == IBUS_ENGINE_PREEDIT_COMMIT) {
186ff6
+            if (context->client_commit_preedit)
186ff6
+               bus_input_context_clear_preedit_text (context, FALSE);
186ff6
+            else
186ff6
+               bus_input_context_clear_preedit_text (context, TRUE);
186ff6
+        }
186ff6
         bus_engine_proxy_reset (context->engine);
186ff6
     }
186ff6
     g_dbus_method_invocation_return_value (invocation, NULL);
186ff6
@@ -1248,6 +1261,13 @@ _ic_set_content_type (BusInputContext *c
186ff6
     }
186ff6
 }
186ff6
 
186ff6
+static void
186ff6
+_ic_set_client_commit_preedit (BusInputContext *context,
186ff6
+                               GVariant        *value)
186ff6
+{
186ff6
+    g_variant_get (value, "(b)", &context->client_commit_preedit);
186ff6
+}
186ff6
+
186ff6
 static gboolean
186ff6
 bus_input_context_service_set_property (IBusService     *service,
186ff6
                                         GDBusConnection *connection,
186ff6
@@ -1270,9 +1290,14 @@ bus_input_context_service_set_property (
186ff6
                                   error);
186ff6
     }
186ff6
 
186ff6
+    g_return_val_if_fail (BUS_IS_INPUT_CONTEXT (service), FALSE);
186ff6
+
186ff6
     if (g_strcmp0 (property_name, "ContentType") == 0) {
186ff6
-        BusInputContext *context = (BusInputContext *) service;
186ff6
-        _ic_set_content_type (context, value);
186ff6
+        _ic_set_content_type (BUS_INPUT_CONTEXT (service), value);
186ff6
+        return TRUE;
186ff6
+    }
186ff6
+    if (g_strcmp0 (property_name, "ClientCommitPreedit") == 0) {
186ff6
+        _ic_set_client_commit_preedit (BUS_INPUT_CONTEXT (service), value);
186ff6
         return TRUE;
186ff6
     }
186ff6
 
186ff6
@@ -1343,22 +1368,44 @@ bus_input_context_focus_in (BusInputCont
186ff6
 
186ff6
 /**
186ff6
  * bus_input_context_clear_preedit_text:
186ff6
+ * @context: A #BusInputContext
186ff6
+ * @with_signal: %FALSE if the preedit is already updated in ibus clients
186ff6
+ *               likes ibus-im.so. Otherwise %TRUE.
186ff6
  *
186ff6
- * Clear context->preedit_text. If the preedit mode is IBUS_ENGINE_PREEDIT_COMMIT, commit it before clearing.
186ff6
+ * Clear context->preedit_text. If the preedit mode is
186ff6
+ * IBUS_ENGINE_PREEDIT_COMMIT, commit it before clearing.
186ff6
  */
186ff6
-static void
186ff6
-bus_input_context_clear_preedit_text (BusInputContext *context)
186ff6
+void
186ff6
+bus_input_context_clear_preedit_text (BusInputContext *context,
186ff6
+                                      gboolean         with_signal)
186ff6
 {
186ff6
+    IBusText *preedit_text;
186ff6
+    guint     preedit_mode;
186ff6
+    gboolean  preedit_visible;
186ff6
+
186ff6
     g_assert (BUS_IS_INPUT_CONTEXT (context));
186ff6
 
186ff6
-    if (context->preedit_visible &&
186ff6
-        context->preedit_mode == IBUS_ENGINE_PREEDIT_COMMIT) {
186ff6
-        bus_input_context_commit_text (context, context->preedit_text);
186ff6
+    if (!with_signal) {
186ff6
+        g_object_unref (context->preedit_text);
186ff6
+        context->preedit_mode = IBUS_ENGINE_PREEDIT_CLEAR;
186ff6
+        context->preedit_text = (IBusText *) g_object_ref_sink (text_empty);
186ff6
+        context->preedit_cursor_pos = 0;
186ff6
+        context->preedit_visible = FALSE;
186ff6
+        return;
186ff6
     }
186ff6
 
186ff6
-    /* always clear preedit text */
186ff6
+    /* always clear preedit text to reset the cursor position in the
186ff6
+     * client application before commit the preeit text. */
186ff6
+    preedit_text = g_object_ref (context->preedit_text);
186ff6
+    preedit_mode = context->preedit_mode;
186ff6
+    preedit_visible = context->preedit_visible;
186ff6
     bus_input_context_update_preedit_text (context,
186ff6
         text_empty, 0, FALSE, IBUS_ENGINE_PREEDIT_CLEAR);
186ff6
+
186ff6
+    if (preedit_visible && preedit_mode == IBUS_ENGINE_PREEDIT_COMMIT) {
186ff6
+        bus_input_context_commit_text (context, preedit_text);
186ff6
+    }
186ff6
+    g_object_unref (preedit_text);
186ff6
 }
186ff6
 
186ff6
 void
186ff6
@@ -1369,7 +1416,10 @@ bus_input_context_focus_out (BusInputCon
186ff6
     if (!context->has_focus)
186ff6
         return;
186ff6
 
186ff6
-    bus_input_context_clear_preedit_text (context);
186ff6
+    if (context->client_commit_preedit)
186ff6
+        bus_input_context_clear_preedit_text (context, FALSE);
186ff6
+    else
186ff6
+        bus_input_context_clear_preedit_text (context, TRUE);
186ff6
     bus_input_context_update_auxiliary_text (context, text_empty, FALSE);
186ff6
     bus_input_context_update_lookup_table (context, lookup_table_empty, FALSE);
186ff6
     bus_input_context_register_properties (context, props_empty);
186ff6
@@ -1455,11 +1505,28 @@ bus_input_context_update_preedit_text (B
186ff6
     context->preedit_mode = mode;
186ff6
 
186ff6
     if (PREEDIT_CONDITION) {
186ff6
-        GVariant *variant = ibus_serializable_serialize ((IBusSerializable *)context->preedit_text);
186ff6
-        bus_input_context_emit_signal (context,
186ff6
-                                       "UpdatePreeditText",
186ff6
-                                       g_variant_new ("(vub)", variant, context->preedit_cursor_pos, context->preedit_visible),
186ff6
-                                       NULL);
186ff6
+        GVariant *variant = ibus_serializable_serialize (
186ff6
+                (IBusSerializable *)context->preedit_text);
186ff6
+        if (context->client_commit_preedit) {
186ff6
+            bus_input_context_emit_signal (
186ff6
+                    context,
186ff6
+                    "UpdatePreeditTextWithMode",
186ff6
+                    g_variant_new ("(vubu)",
186ff6
+                                   variant,
186ff6
+                                   context->preedit_cursor_pos,
186ff6
+                                   context->preedit_visible,
186ff6
+                                   context->preedit_mode),
186ff6
+                    NULL);
186ff6
+        } else {
186ff6
+            bus_input_context_emit_signal (
186ff6
+                    context,
186ff6
+                    "UpdatePreeditText",
186ff6
+                    g_variant_new ("(vub)",
186ff6
+                                   variant,
186ff6
+                                   context->preedit_cursor_pos,
186ff6
+                                   context->preedit_visible),
186ff6
+                    NULL);
186ff6
+        }
186ff6
     }
186ff6
     else {
186ff6
         g_signal_emit (context,
186ff6
@@ -2187,7 +2254,7 @@ bus_input_context_disable (BusInputConte
186ff6
 {
186ff6
     g_assert (BUS_IS_INPUT_CONTEXT (context));
186ff6
 
186ff6
-    bus_input_context_clear_preedit_text (context);
186ff6
+    bus_input_context_clear_preedit_text (context, TRUE);
186ff6
     bus_input_context_update_auxiliary_text (context, text_empty, FALSE);
186ff6
     bus_input_context_update_lookup_table (context, lookup_table_empty, FALSE);
186ff6
     bus_input_context_register_properties (context, props_empty);
186ff6
@@ -2230,7 +2297,7 @@ bus_input_context_unset_engine (BusInput
186ff6
 {
186ff6
     g_assert (BUS_IS_INPUT_CONTEXT (context));
186ff6
 
186ff6
-    bus_input_context_clear_preedit_text (context);
186ff6
+    bus_input_context_clear_preedit_text (context, TRUE);
186ff6
     bus_input_context_update_auxiliary_text (context, text_empty, FALSE);
186ff6
     bus_input_context_update_lookup_table (context, lookup_table_empty, FALSE);
186ff6
     bus_input_context_register_properties (context, props_empty);
186ff6
diff --git a/bus/inputcontext.h b/bus/inputcontext.h
186ff6
index a46d5c06..7105fff8 100644
186ff6
--- a/bus/inputcontext.h
186ff6
+++ b/bus/inputcontext.h
186ff6
@@ -2,8 +2,8 @@
186ff6
 /* vim:set et sts=4: */
186ff6
 /* ibus - The Input Bus
186ff6
  * Copyright (C) 2008-2014 Peng Huang <shawn.p.huang@gmail.com>
186ff6
- * Copyright (C) 2017 Takao Fujiwara <takao.fujiwara1@gmail.com>
186ff6
- * Copyright (C) 2008-2014 Red Hat, Inc.
186ff6
+ * Copyright (C) 2017-2018 Takao Fujiwara <takao.fujiwara1@gmail.com>
186ff6
+ * Copyright (C) 2008-2018 Red Hat, Inc.
186ff6
  *
186ff6
  * This library is free software; you can redistribute it and/or
186ff6
  * modify it under the terms of the GNU Lesser General Public
186ff6
@@ -269,5 +269,19 @@ void                 bus_input_context_c
186ff6
                                                 (BusInputContext *context,
186ff6
                                                  IBusText        *text);
186ff6
 
186ff6
+/**
186ff6
+ * bus_input_context_clear_preedit_text:
186ff6
+ *
186ff6
+ * Clear context->preedit_text. If the preedit mode is
186ff6
+ * IBUS_ENGINE_PREEDIT_COMMIT and with_signal is %TRUE, commit it before
186ff6
+ * clearing.
186ff6
+ * If with_signal is %FALSE, this just clears the preedit coditions
186ff6
+ * and the actual preedit is handled in ibus clients.
186ff6
+ */
186ff6
+void                 bus_input_context_clear_preedit_text
186ff6
+                                                (BusInputContext    *context,
186ff6
+                                                 gboolean
186ff6
+                                                                   with_signal);
186ff6
+
186ff6
 G_END_DECLS
186ff6
 #endif
186ff6
diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c
186ff6
index e4de52d9..73a0eaec 100644
186ff6
--- a/client/gtk2/ibusimcontext.c
186ff6
+++ b/client/gtk2/ibusimcontext.c
186ff6
@@ -2,8 +2,8 @@
186ff6
 /* vim:set et sts=4: */
186ff6
 /* ibus - The Input Bus
186ff6
  * Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
186ff6
- * Copyright (C) 2015-2017 Takao Fujiwara <takao.fujiwara1@gmail.com>
186ff6
- * Copyright (C) 2008-2017 Red Hat, Inc.
186ff6
+ * Copyright (C) 2015-2018 Takao Fujiwara <takao.fujiwara1@gmail.com>
186ff6
+ * Copyright (C) 2008-2018 Red Hat, Inc.
186ff6
  *
186ff6
  * This library is free software; you can redistribute it and/or
186ff6
  * modify it under the terms of the GNU Lesser General Public
186ff6
@@ -61,6 +61,7 @@ struct _IBusIMContext {
186ff6
     PangoAttrList   *preedit_attrs;
186ff6
     gint             preedit_cursor_pos;
186ff6
     gboolean         preedit_visible;
186ff6
+    guint            preedit_mode;
186ff6
 
186ff6
     GdkRectangle     cursor_area;
186ff6
     gboolean         has_focus;
186ff6
@@ -132,8 +133,14 @@ static void     ibus_im_context_set_surrounding
186ff6
                                              gint           len,
186ff6
                                              gint           cursor_index);
186ff6
 
186ff6
-
186ff6
 /* static methods*/
186ff6
+static void     _ibus_context_update_preedit_text_cb
186ff6
+                                           (IBusInputContext   *ibuscontext,
186ff6
+                                            IBusText           *text,
186ff6
+                                            gint                cursor_pos,
186ff6
+                                            gboolean            visible,
186ff6
+                                            guint               mode,
186ff6
+                                            IBusIMContext      *ibusimcontext);
186ff6
 static void     _create_input_context       (IBusIMContext      *context);
186ff6
 static gboolean _set_cursor_location_internal
186ff6
                                             (IBusIMContext      *context);
186ff6
@@ -744,6 +751,7 @@ ibus_im_context_init (GObject *obj)
186ff6
     ibusimcontext->preedit_attrs = NULL;
186ff6
     ibusimcontext->preedit_cursor_pos = 0;
186ff6
     ibusimcontext->preedit_visible = FALSE;
186ff6
+    ibusimcontext->preedit_mode = IBUS_ENGINE_PREEDIT_CLEAR;
186ff6
 
186ff6
     // Init cursor area
186ff6
     ibusimcontext->cursor_area.x = -1;
186ff6
@@ -854,6 +862,24 @@ ibus_im_context_finalize (GObject *obj)
186ff6
     G_OBJECT_CLASS(parent_class)->finalize (obj);
186ff6
 }
186ff6
 
186ff6
+static void
186ff6
+ibus_im_context_clear_preedit_text (IBusIMContext *ibusimcontext)
186ff6
+{
186ff6
+    g_assert (ibusimcontext->ibuscontext);
186ff6
+    if (ibusimcontext->preedit_visible &&
186ff6
+        ibusimcontext->preedit_mode == IBUS_ENGINE_PREEDIT_COMMIT) {
186ff6
+        gchar *preedit_string = g_strdup (ibusimcontext->preedit_string);
186ff6
+        _ibus_context_update_preedit_text_cb (ibusimcontext->ibuscontext,
186ff6
+                                              ibus_text_new_from_string (""),
186ff6
+                                              0,
186ff6
+                                              FALSE,
186ff6
+                                              IBUS_ENGINE_PREEDIT_CLEAR,
186ff6
+                                              ibusimcontext);
186ff6
+        g_signal_emit (ibusimcontext, _signal_commit_id, 0, preedit_string);
186ff6
+        g_free (preedit_string);
186ff6
+    }
186ff6
+}
186ff6
+
186ff6
 static gboolean
186ff6
 ibus_im_context_filter_keypress (GtkIMContext *context,
186ff6
                                  GdkEventKey  *event)
186ff6
@@ -1003,6 +1029,7 @@ ibus_im_context_focus_out (GtkIMContext *context)
186ff6
 
186ff6
     ibusimcontext->has_focus = FALSE;
186ff6
     if (ibusimcontext->ibuscontext) {
186ff6
+        ibus_im_context_clear_preedit_text (ibusimcontext);
186ff6
         ibus_input_context_focus_out (ibusimcontext->ibuscontext);
186ff6
     }
186ff6
 
186ff6
@@ -1022,6 +1049,12 @@ ibus_im_context_reset (GtkIMContext *context)
186ff6
     IBusIMContext *ibusimcontext = IBUS_IM_CONTEXT (context);
186ff6
 
186ff6
     if (ibusimcontext->ibuscontext) {
186ff6
+        /* Commented out ibus_im_context_clear_preedit_text().
186ff6
+         * Hangul needs to receive the reset callback with button press
186ff6
+         * but other IMEs should avoid to receive the reset callback
186ff6
+         * so the signal would need to be customized with GtkSetting.
186ff6
+         * IBus uses button-press-event instead.
186ff6
+         */
186ff6
         ibus_input_context_reset (ibusimcontext->ibuscontext);
186ff6
     }
186ff6
     gtk_im_context_reset (ibusimcontext->slave);
186ff6
@@ -1068,21 +1101,67 @@ ibus_im_context_get_preedit_string (GtkIMContext   *context,
186ff6
 }
186ff6
 
186ff6
 
186ff6
+static gboolean
186ff6
+ibus_im_context_button_press_event_cb (GtkWidget      *widget,
186ff6
+                                       GdkEventButton *event,
186ff6
+                                       IBusIMContext  *ibusimcontext)
186ff6
+{
186ff6
+    if (event->button != 1)
186ff6
+        return FALSE;
186ff6
+
186ff6
+    if (ibusimcontext->preedit_visible &&
186ff6
+        ibusimcontext->preedit_mode == IBUS_ENGINE_PREEDIT_COMMIT) {
186ff6
+        ibus_im_context_clear_preedit_text (ibusimcontext);
186ff6
+        if (ibusimcontext->ibuscontext)
186ff6
+            ibus_input_context_reset (ibusimcontext->ibuscontext);
186ff6
+    }
186ff6
+    return FALSE;
186ff6
+}
186ff6
+
186ff6
 static void
186ff6
 ibus_im_context_set_client_window (GtkIMContext *context, GdkWindow *client)
186ff6
 {
186ff6
+    IBusIMContext *ibusimcontext;
186ff6
+#if !GTK_CHECK_VERSION (3, 93, 0)
186ff6
+    GtkWidget *widget;
186ff6
+#endif
186ff6
+
186ff6
     IDEBUG ("%s", __FUNCTION__);
186ff6
 
186ff6
-    IBusIMContext *ibusimcontext = IBUS_IM_CONTEXT (context);
186ff6
+    ibusimcontext = IBUS_IM_CONTEXT (context);
186ff6
 
186ff6
     if (ibusimcontext->client_window) {
186ff6
+#if !GTK_CHECK_VERSION (3, 93, 0)
186ff6
+        gdk_window_get_user_data (ibusimcontext->client_window,
186ff6
+                                  (gpointer *)&widget);
186ff6
+        /* firefox needs GtkWidget instead of GtkWindow */
186ff6
+        if (GTK_IS_WIDGET (widget)) {
186ff6
+            g_signal_handlers_disconnect_by_func (
186ff6
+                    widget,
186ff6
+                    (GCallback)ibus_im_context_button_press_event_cb,
186ff6
+                    ibusimcontext);
186ff6
+        }
186ff6
+#endif
186ff6
         g_object_unref (ibusimcontext->client_window);
186ff6
         ibusimcontext->client_window = NULL;
186ff6
     }
186ff6
 
186ff6
-    if (client != NULL)
186ff6
+    if (client != NULL) {
186ff6
         ibusimcontext->client_window = g_object_ref (client);
186ff6
+#if !GTK_CHECK_VERSION (3, 93, 0)
186ff6
+        gdk_window_get_user_data (ibusimcontext->client_window,
186ff6
+                                  (gpointer *)&widget);
186ff6
 
186ff6
+        /* firefox needs GtkWidget instead of GtkWindow */
186ff6
+        if (GTK_IS_WIDGET (widget)) {
186ff6
+            g_signal_connect (
186ff6
+                    widget,
186ff6
+                    "button-press-event",
186ff6
+                    G_CALLBACK (ibus_im_context_button_press_event_cb),
186ff6
+                    ibusimcontext);
186ff6
+        }
186ff6
+#endif
186ff6
+    }
186ff6
     if (ibusimcontext->slave)
186ff6
         gtk_im_context_set_client_window (ibusimcontext->slave, client);
186ff6
 }
186ff6
@@ -1530,6 +1609,7 @@ _ibus_context_update_preedit_text_cb (IBusInputContext  *ibuscontext,
186ff6
                                       IBusText          *text,
186ff6
                                       gint               cursor_pos,
186ff6
                                       gboolean           visible,
186ff6
+                                      guint              mode,
186ff6
                                       IBusIMContext     *ibusimcontext)
186ff6
 {
186ff6
     IDEBUG ("%s", __FUNCTION__);
186ff6
@@ -1586,6 +1666,7 @@ _ibus_context_update_preedit_text_cb (IBusInputContext  *ibuscontext,
186ff6
 
186ff6
     flag = ibusimcontext->preedit_visible != visible;
186ff6
     ibusimcontext->preedit_visible = visible;
186ff6
+    ibusimcontext->preedit_mode = mode;
186ff6
 
186ff6
     if (ibusimcontext->preedit_visible) {
186ff6
         if (flag) {
186ff6
@@ -1676,7 +1757,7 @@ _create_input_context_done (IBusBus       *bus,
186ff6
         g_error_free (error);
186ff6
     }
186ff6
     else {
186ff6
-
186ff6
+        ibus_input_context_set_client_commit_preedit (context, TRUE);
186ff6
         ibusimcontext->ibuscontext = context;
186ff6
 
186ff6
         g_signal_connect (ibusimcontext->ibuscontext,
186ff6
@@ -1692,7 +1773,7 @@ _create_input_context_done (IBusBus       *bus,
186ff6
                           G_CALLBACK (_ibus_context_delete_surrounding_text_cb),
186ff6
                           ibusimcontext);
186ff6
         g_signal_connect (ibusimcontext->ibuscontext,
186ff6
-                          "update-preedit-text",
186ff6
+                          "update-preedit-text-with-mode",
186ff6
                           G_CALLBACK (_ibus_context_update_preedit_text_cb),
186ff6
                           ibusimcontext);
186ff6
         g_signal_connect (ibusimcontext->ibuscontext,
186ff6
diff --git a/src/ibusinputcontext.c b/src/ibusinputcontext.c
186ff6
index ae7048ad..a809ef08 100644
186ff6
--- a/src/ibusinputcontext.c
186ff6
+++ b/src/ibusinputcontext.c
186ff6
@@ -2,7 +2,8 @@
186ff6
 /* vim:set et sts=4: */
186ff6
 /* ibus - The Input Bus
186ff6
  * Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
186ff6
- * Copyright (C) 2008-2013 Red Hat, Inc.
186ff6
+ * Copyright (C) 2018 Takao Fujiwara <takao.fujiwara1@gmail.com>
186ff6
+ * Copyright (C) 2008-2018 Red Hat, Inc.
186ff6
  *
186ff6
  * This library is free software; you can redistribute it and/or
186ff6
  * modify it under the terms of the GNU Lesser General Public
186ff6
@@ -39,6 +40,7 @@ enum {
186ff6
     FORWARD_KEY_EVENT,
186ff6
     DELETE_SURROUNDING_TEXT,
186ff6
     UPDATE_PREEDIT_TEXT,
186ff6
+    UPDATE_PREEDIT_TEXT_WITH_MODE,
186ff6
     SHOW_PREEDIT_TEXT,
186ff6
     HIDE_PREEDIT_TEXT,
186ff6
     UPDATE_AUXILIARY_TEXT,
186ff6
@@ -217,6 +219,34 @@ ibus_input_context_class_init (IBusInputContextClass *class)
186ff6
             G_TYPE_UINT,
186ff6
             G_TYPE_BOOLEAN);
186ff6
 
186ff6
+    /**
186ff6
+     * IBusInputContext::update-preedit-text-with-mode:
186ff6
+     * @context: An IBusInputContext.
186ff6
+     * @text: Text to be updated.
186ff6
+     * @cursor_pos: Cursor position.
186ff6
+     * @visible: Whether the update is visible.
186ff6
+     * @mode: Preedit mode.
186ff6
+     *
186ff6
+     * Emitted to update preedit text with the mode.
186ff6
+     *
186ff6
+     * (Note: The text object is floating, and it will be released after the
186ff6
+     *  signal. If signal handler wants to keep the object, the handler should
186ff6
+     *  use g_object_ref_sink() to get the ownership of the object.)
186ff6
+     */
186ff6
+    context_signals[UPDATE_PREEDIT_TEXT_WITH_MODE] =
186ff6
+        g_signal_new (I_("update-preedit-text-with-mode"),
186ff6
+            G_TYPE_FROM_CLASS (class),
186ff6
+            G_SIGNAL_RUN_LAST,
186ff6
+            0,
186ff6
+            NULL, NULL,
186ff6
+            _ibus_marshal_VOID__OBJECT_UINT_BOOLEAN_UINT,
186ff6
+            G_TYPE_NONE,
186ff6
+            4,
186ff6
+            IBUS_TYPE_TEXT,
186ff6
+            G_TYPE_UINT,
186ff6
+            G_TYPE_BOOLEAN,
186ff6
+            G_TYPE_UINT);
186ff6
+
186ff6
     /**
186ff6
      * IBusInputContext::show-preedit-text:
186ff6
      * @context: An IBusInputContext.
186ff6
@@ -542,6 +572,28 @@ ibus_input_context_g_signal (GDBusProxy  *proxy,
186ff6
             g_object_unref (text);
186ff6
         return;
186ff6
     }
186ff6
+    if (g_strcmp0 (signal_name, "UpdatePreeditTextWithMode") == 0) {
186ff6
+        GVariant *variant = NULL;
186ff6
+        gint32 cursor_pos;
186ff6
+        gboolean visible;
186ff6
+        guint mode = 0;
186ff6
+        g_variant_get (parameters,
186ff6
+                       "(vubu)", &variant, &cursor_pos, &visible, &mode);
186ff6
+        IBusText *text = IBUS_TEXT (ibus_serializable_deserialize (variant));
186ff6
+        g_variant_unref (variant);
186ff6
+
186ff6
+        g_signal_emit (context,
186ff6
+                       context_signals[UPDATE_PREEDIT_TEXT_WITH_MODE],
186ff6
+                       0,
186ff6
+                       text,
186ff6
+                       cursor_pos,
186ff6
+                       visible,
186ff6
+                       mode);
186ff6
+
186ff6
+        if (g_object_is_floating (text))
186ff6
+            g_object_unref (text);
186ff6
+        return;
186ff6
+    }
186ff6
 
186ff6
     /* lookup signal in table */
186ff6
     gint i;
186ff6
@@ -1043,10 +1095,11 @@ ibus_input_context_set_surrounding_text (IBusInputContext   *context,
186ff6
                                          guint32             cursor_pos,
186ff6
                                          guint32             anchor_pos)
186ff6
 {
186ff6
+    IBusInputContextPrivate *priv;
186ff6
+
186ff6
     g_assert (IBUS_IS_INPUT_CONTEXT (context));
186ff6
     g_assert (IBUS_IS_TEXT (text));
186ff6
 
186ff6
-    IBusInputContextPrivate *priv;
186ff6
     priv = IBUS_INPUT_CONTEXT_GET_PRIVATE (context);
186ff6
 
186ff6
     if (cursor_pos != priv->surrounding_cursor_pos ||
186ff6
@@ -1090,12 +1143,15 @@ ibus_input_context_set_content_type (IBusInputContext *context,
186ff6
                                      guint             purpose,
186ff6
                                      guint             hints)
186ff6
 {
186ff6
+    GVariant *cached_content_type;
186ff6
+    GVariant *content_type;
186ff6
+
186ff6
     g_assert (IBUS_IS_INPUT_CONTEXT (context));
186ff6
 
186ff6
-    GVariant *cached_content_type =
186ff6
+    cached_content_type =
186ff6
         g_dbus_proxy_get_cached_property ((GDBusProxy *) context,
186ff6
                                           "ContentType");
186ff6
-    GVariant *content_type = g_variant_new ("(uu)", purpose, hints);
186ff6
+    content_type = g_variant_new ("(uu)", purpose, hints);
186ff6
 
186ff6
     g_variant_ref_sink (content_type);
186ff6
     if (cached_content_type == NULL ||
186ff6
@@ -1142,18 +1198,22 @@ ibus_input_context_get_engine_async_finish (IBusInputContext   *context,
186ff6
                                             GAsyncResult       *res,
186ff6
                                             GError            **error)
186ff6
 {
186ff6
+    GVariant *variant;
186ff6
+    GVariant *engine_desc_variant;
186ff6
+    IBusEngineDesc *desc;
186ff6
+
186ff6
     g_assert (IBUS_IS_INPUT_CONTEXT (context));
186ff6
     g_assert (G_IS_ASYNC_RESULT (res));
186ff6
     g_assert (error == NULL || *error == NULL);
186ff6
 
186ff6
-    GVariant *variant = g_dbus_proxy_call_finish ((GDBusProxy *) context,
186ff6
-                                                   res, error);
186ff6
+    variant = g_dbus_proxy_call_finish ((GDBusProxy *) context, res, error);
186ff6
     if (variant == NULL) {
186ff6
         return NULL;
186ff6
     }
186ff6
 
186ff6
-    GVariant *engine_desc_variant = g_variant_get_child_value (variant, 0);
186ff6
-    IBusEngineDesc *desc = IBUS_ENGINE_DESC (ibus_serializable_deserialize (engine_desc_variant));
186ff6
+    engine_desc_variant = g_variant_get_child_value (variant, 0);
186ff6
+    desc = IBUS_ENGINE_DESC (
186ff6
+            ibus_serializable_deserialize (engine_desc_variant));
186ff6
     g_variant_unref (engine_desc_variant);
186ff6
     g_variant_unref (variant);
186ff6
 
186ff6
@@ -1163,9 +1223,13 @@ ibus_input_context_get_engine_async_finish (IBusInputContext   *context,
186ff6
 IBusEngineDesc *
186ff6
 ibus_input_context_get_engine (IBusInputContext *context)
186ff6
 {
186ff6
-    g_assert (IBUS_IS_INPUT_CONTEXT (context));
186ff6
     GVariant *result = NULL;
186ff6
     GError *error = NULL;
186ff6
+    GVariant *engine_desc_variant;
186ff6
+    IBusEngineDesc *desc;
186ff6
+
186ff6
+    g_assert (IBUS_IS_INPUT_CONTEXT (context));
186ff6
+
186ff6
     result = g_dbus_proxy_call_sync ((GDBusProxy *) context,
186ff6
                                      "GetEngine",               /* method_name */
186ff6
                                      NULL,                      /* parameters */
186ff6
@@ -1189,8 +1253,9 @@ ibus_input_context_get_engine (IBusInputContext *context)
186ff6
         return NULL;
186ff6
     }
186ff6
 
186ff6
-    GVariant *engine_desc_variant = g_variant_get_child_value (result, 0);
186ff6
-    IBusEngineDesc *desc = IBUS_ENGINE_DESC (ibus_serializable_deserialize (engine_desc_variant));
186ff6
+    engine_desc_variant = g_variant_get_child_value (result, 0);
186ff6
+    desc = IBUS_ENGINE_DESC (
186ff6
+            ibus_serializable_deserialize (engine_desc_variant));
186ff6
     g_variant_unref (engine_desc_variant);
186ff6
     g_variant_unref (result);
186ff6
 
186ff6
@@ -1214,6 +1279,41 @@ ibus_input_context_set_engine (IBusInputContext *context,
186ff6
                        );
186ff6
 }
186ff6
 
186ff6
+void
186ff6
+ibus_input_context_set_client_commit_preedit (IBusInputContext *context,
186ff6
+                                              gboolean          client_commit)
186ff6
+{
186ff6
+    GVariant *cached_content_type;
186ff6
+    GVariant *var_client_commit;
186ff6
+
186ff6
+    g_assert (IBUS_IS_INPUT_CONTEXT (context));
186ff6
+
186ff6
+    cached_content_type =
186ff6
+        g_dbus_proxy_get_cached_property ((GDBusProxy *) context,
186ff6
+                                          "ClientCommitPreedit");
186ff6
+    var_client_commit = g_variant_new ("(b)", client_commit);
186ff6
+
186ff6
+    g_variant_ref_sink (var_client_commit);
186ff6
+    if (cached_content_type == NULL) {
186ff6
+        g_dbus_proxy_call ((GDBusProxy *) context,
186ff6
+                           "org.freedesktop.DBus.Properties.Set",
186ff6
+                           g_variant_new ("(ssv)",
186ff6
+                                          IBUS_INTERFACE_INPUT_CONTEXT,
186ff6
+                                          "ClientCommitPreedit",
186ff6
+                                          var_client_commit),
186ff6
+                           G_DBUS_CALL_FLAGS_NONE,
186ff6
+                           -1,
186ff6
+                           NULL, /* cancellable */
186ff6
+                           NULL, /* callback */
186ff6
+                           NULL  /* user_data */
186ff6
+                           );
186ff6
+    }
186ff6
+
186ff6
+    if (cached_content_type != NULL)
186ff6
+        g_variant_unref (cached_content_type);
186ff6
+    g_variant_unref (var_client_commit);
186ff6
+}
186ff6
+
186ff6
 #define DEFINE_FUNC(name, Name)                                         \
186ff6
     void                                                                \
186ff6
     ibus_input_context_##name (IBusInputContext *context)               \
186ff6
diff --git a/src/ibusinputcontext.h b/src/ibusinputcontext.h
186ff6
index a77cf92f..09992148 100644
186ff6
--- a/src/ibusinputcontext.h
186ff6
+++ b/src/ibusinputcontext.h
186ff6
@@ -2,7 +2,8 @@
186ff6
 /* vim:set et sts=4: */
186ff6
 /* ibus - The Input Bus
186ff6
  * Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
186ff6
- * Copyright (C) 2008-2013 Red Hat, Inc.
186ff6
+ * Copyright (C) 2018 Takao Fujiwara <takao.fujiwara1@gmail.com>
186ff6
+ * Copyright (C) 2008-2018 Red Hat, Inc.
186ff6
  *
186ff6
  * This library is free software; you can redistribute it and/or
186ff6
  * modify it under the terms of the GNU Lesser General Public
186ff6
@@ -498,5 +499,29 @@ void         ibus_input_context_set_content_type
186ff6
                                              guint               purpose,
186ff6
                                              guint               hints);
186ff6
 
186ff6
+/**
186ff6
+ * ibus_input_context_set_client_commit_preedit:
186ff6
+ * @context: An #IBusInputContext.
186ff6
+ * @client_commit: %TRUE if your input context commits pre-edit texts
186ff6
+ *     with Space or Enter key events or mouse click events. %FALSE if
186ff6
+ *     ibus-daemon commits pre-edit texts with those events.
186ff6
+ *     The default is %FALSE. The behavior is decided with
186ff6
+ *     ibus_engine_update_preedit_text_with_mode() to commit, clear or
186ff6
+ *     keep the pre-edit text and this API is important in ibus-hangul.
186ff6
+ *
186ff6
+ * Set whether #IBusInputContext commits pre-edit texts or not.
186ff6
+ * If %TRUE, 'update-preedit-text-with-mode' signal is emitted
186ff6
+ * instead of 'update-preedit-text' signal.
186ff6
+ * If your client receives the 'update-preedit-text-with-mode' signal,
186ff6
+ * the client needs to implement commit_text() of pre-edit text when
186ff6
+ * GtkIMContextClass.focus_out() is called in case an IME desires that
186ff6
+ * behavior but it depends on each IME.
186ff6
+ *
186ff6
+ * See also ibus_engine_update_preedit_text_with_mode().
186ff6
+ */
186ff6
+void         ibus_input_context_set_client_commit_preedit (
186ff6
+                                             IBusInputContext   *context,
186ff6
+                                             gboolean            client_commit);
186ff6
+
186ff6
 G_END_DECLS
186ff6
 #endif
186ff6
-- 
186ff6
2.19.1
186ff6
186ff6
From 7b3b8c8b0c6a41ab524e0be9474825da9cba96ac Mon Sep 17 00:00:00 2001
186ff6
From: fujiwarat <takao.fujiwara1@gmail.com>
186ff6
Date: Tue, 13 Nov 2018 14:27:52 +0900
186ff6
Subject: [PATCH 2/4] client/gtk2: Do not delete IBUS_CAP_SURROUNDING_TEXT
186ff6
186ff6
retrieve-surrounding signal could be failed with the first typing
186ff6
on firefox. It could be a bug in firefox but now IBusIMContext does not
186ff6
delete IBUS_CAP_SURROUNDING_TEXT in the capabilities as a workaround
186ff6
when retrieve-surrounding signal is failed.
186ff6
Also added retrieve-surrounding signal after some committing text.
186ff6
186ff6
BUG=https://github.com/ibus/ibus/issues/2054
186ff6
---
186ff6
 client/gtk2/ibusimcontext.c | 11 ++++++++---
186ff6
 1 file changed, 8 insertions(+), 3 deletions(-)
186ff6
186ff6
diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c
186ff6
index 73a0eaec..82af51a1 100644
186ff6
--- a/client/gtk2/ibusimcontext.c
186ff6
+++ b/client/gtk2/ibusimcontext.c
186ff6
@@ -298,6 +298,7 @@ ibus_im_context_commit_event (IBusIMContext *ibusimcontext,
186ff6
         IBusText *text = ibus_text_new_from_unichar (ch);
186ff6
         g_signal_emit (ibusimcontext, _signal_commit_id, 0, text->text);
186ff6
         g_object_unref (text);
186ff6
+        _request_surrounding_text (ibusimcontext);
186ff6
         return TRUE;
186ff6
     }
186ff6
    return FALSE;
186ff6
@@ -386,9 +387,12 @@ _request_surrounding_text (IBusIMContext *context)
186ff6
         g_signal_emit (context, _signal_retrieve_surrounding_id, 0,
186ff6
                        &return_value);
186ff6
         if (!return_value) {
186ff6
-            context->caps &= ~IBUS_CAP_SURROUNDING_TEXT;
186ff6
-            ibus_input_context_set_capabilities (context->ibuscontext,
186ff6
-                                                 context->caps);
186ff6
+            /* #2054 firefox::IMContextWrapper::GetCurrentParagraph() could
186ff6
+             * fail with the first typing on firefox but it succeeds with
186ff6
+             * the second typing.
186ff6
+             */
186ff6
+            g_warning ("%s has no capability of surrounding-text feature",
186ff6
+                       g_get_prgname ());
186ff6
         }
186ff6
     }
186ff6
 }
186ff6
@@ -877,6 +881,7 @@ ibus_im_context_clear_preedit_text (IBusIMContext *ibusimcontext)
186ff6
                                               ibusimcontext);
186ff6
         g_signal_emit (ibusimcontext, _signal_commit_id, 0, preedit_string);
186ff6
         g_free (preedit_string);
186ff6
+        _request_surrounding_text (ibusimcontext);
186ff6
     }
186ff6
 }
186ff6
 
186ff6
-- 
186ff6
2.19.1
186ff6
186ff6
From 4c40afba9c862b4f6651b1b971553e5e89e83343 Mon Sep 17 00:00:00 2001
186ff6
From: fujiwarat <takao.fujiwara1@gmail.com>
186ff6
Date: Thu, 6 Dec 2018 16:53:57 +0900
186ff6
Subject: [PATCH 3/4] client/gtk2: Always reset and clear preedit on mouse
186ff6
 click
186ff6
186ff6
Thinking about the reset signal again, now I think it's good to emit
186ff6
the reset signal and clear the preedit on mouse click for any engines
186ff6
besides Hangul because the behavior could be handled by each engine
186ff6
with the reset signal.
186ff6
186ff6
BUG=https://github.com/ibus/ibus/issues/1980
186ff6
---
186ff6
 client/gtk2/ibusimcontext.c | 26 +++++++++++++-------------
186ff6
 1 file changed, 13 insertions(+), 13 deletions(-)
186ff6
186ff6
diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c
186ff6
index 82af51a1..ed7fea6e 100644
186ff6
--- a/client/gtk2/ibusimcontext.c
186ff6
+++ b/client/gtk2/ibusimcontext.c
186ff6
@@ -869,16 +869,19 @@ ibus_im_context_finalize (GObject *obj)
186ff6
 static void
186ff6
 ibus_im_context_clear_preedit_text (IBusIMContext *ibusimcontext)
186ff6
 {
186ff6
+    gchar *preedit_string = NULL;
186ff6
     g_assert (ibusimcontext->ibuscontext);
186ff6
     if (ibusimcontext->preedit_visible &&
186ff6
         ibusimcontext->preedit_mode == IBUS_ENGINE_PREEDIT_COMMIT) {
186ff6
-        gchar *preedit_string = g_strdup (ibusimcontext->preedit_string);
186ff6
-        _ibus_context_update_preedit_text_cb (ibusimcontext->ibuscontext,
186ff6
-                                              ibus_text_new_from_string (""),
186ff6
-                                              0,
186ff6
-                                              FALSE,
186ff6
-                                              IBUS_ENGINE_PREEDIT_CLEAR,
186ff6
-                                              ibusimcontext);
186ff6
+        preedit_string = g_strdup (ibusimcontext->preedit_string);
186ff6
+    }
186ff6
+    _ibus_context_update_preedit_text_cb (ibusimcontext->ibuscontext,
186ff6
+                                          ibus_text_new_from_string (""),
186ff6
+                                          0,
186ff6
+                                          FALSE,
186ff6
+                                          IBUS_ENGINE_PREEDIT_CLEAR,
186ff6
+                                          ibusimcontext);
186ff6
+    if (preedit_string) {
186ff6
         g_signal_emit (ibusimcontext, _signal_commit_id, 0, preedit_string);
186ff6
         g_free (preedit_string);
186ff6
         _request_surrounding_text (ibusimcontext);
186ff6
@@ -1114,12 +1117,9 @@ ibus_im_context_button_press_event_cb (GtkWidget      *widget,
186ff6
     if (event->button != 1)
186ff6
         return FALSE;
186ff6
 
186ff6
-    if (ibusimcontext->preedit_visible &&
186ff6
-        ibusimcontext->preedit_mode == IBUS_ENGINE_PREEDIT_COMMIT) {
186ff6
-        ibus_im_context_clear_preedit_text (ibusimcontext);
186ff6
-        if (ibusimcontext->ibuscontext)
186ff6
-            ibus_input_context_reset (ibusimcontext->ibuscontext);
186ff6
-    }
186ff6
+    ibus_im_context_clear_preedit_text (ibusimcontext);
186ff6
+    if (ibusimcontext->ibuscontext)
186ff6
+        ibus_input_context_reset (ibusimcontext->ibuscontext);
186ff6
     return FALSE;
186ff6
 }
186ff6
 
186ff6
-- 
186ff6
2.19.1
186ff6
186ff6
From c7d8771cb9fc652cb638aa7cb8e10ea6b889509e Mon Sep 17 00:00:00 2001
186ff6
From: fujiwarat <takao.fujiwara1@gmail.com>
186ff6
Date: Tue, 11 Dec 2018 19:16:10 +0900
186ff6
Subject: [PATCH 4/4] client/gtk2: Fix SEGV on mouse clicks when ibus-daemon
186ff6
 not running
186ff6
186ff6
---
186ff6
 client/gtk2/ibusimcontext.c | 5 +++--
186ff6
 1 file changed, 3 insertions(+), 2 deletions(-)
186ff6
186ff6
diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c
186ff6
index ed7fea6e..ab7ff88a 100644
186ff6
--- a/client/gtk2/ibusimcontext.c
186ff6
+++ b/client/gtk2/ibusimcontext.c
186ff6
@@ -1117,9 +1117,10 @@ ibus_im_context_button_press_event_cb (GtkWidget      *widget,
186ff6
     if (event->button != 1)
186ff6
         return FALSE;
186ff6
 
186ff6
-    ibus_im_context_clear_preedit_text (ibusimcontext);
186ff6
-    if (ibusimcontext->ibuscontext)
186ff6
+    if (ibusimcontext->ibuscontext) {
186ff6
+        ibus_im_context_clear_preedit_text (ibusimcontext);
186ff6
         ibus_input_context_reset (ibusimcontext->ibuscontext);
186ff6
+    }
186ff6
     return FALSE;
186ff6
 }
186ff6
 
186ff6
-- 
186ff6
2.19.1
186ff6
186ff6
From 9ae2d4658fff3d1e7262fb4fb7ca9ce1af0a27ec Mon Sep 17 00:00:00 2001
186ff6
From: fujiwarat <takao.fujiwara1@gmail.com>
186ff6
Date: Thu, 20 Dec 2018 16:40:31 +0900
186ff6
Subject: [PATCH] client/gtk2: Use button-press-event only with
186ff6
 IBUS_ENGINE_PREEDIT_COMMIT
186ff6
186ff6
BUG=https://github.com/ibus/ibus/issues/1980
186ff6
---
186ff6
 client/gtk2/ibusimcontext.c | 66 ++++++++++++++++++++++++-------------
186ff6
 1 file changed, 43 insertions(+), 23 deletions(-)
186ff6
186ff6
diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c
186ff6
index ab7ff88a..f9310867 100644
186ff6
--- a/client/gtk2/ibusimcontext.c
186ff6
+++ b/client/gtk2/ibusimcontext.c
186ff6
@@ -72,6 +72,8 @@ struct _IBusIMContext {
186ff6
     /* cancellable */
186ff6
     GCancellable    *cancellable;
186ff6
     GQueue          *events_queue;
186ff6
+
186ff6
+    gboolean use_button_press_event;
186ff6
 };
186ff6
 
186ff6
 struct _IBusIMContextClass {
186ff6
@@ -1109,6 +1111,7 @@ ibus_im_context_get_preedit_string (GtkIMContext   *context,
186ff6
 }
186ff6
 
186ff6
 
186ff6
+#if !GTK_CHECK_VERSION (3, 93, 0)
186ff6
 static gboolean
186ff6
 ibus_im_context_button_press_event_cb (GtkWidget      *widget,
186ff6
                                        GdkEventButton *event,
186ff6
@@ -1124,13 +1127,37 @@ ibus_im_context_button_press_event_cb (GtkWidget      *widget,
186ff6
     return FALSE;
186ff6
 }
186ff6
 
186ff6
+static void
186ff6
+_connect_button_press_event (IBusIMContext *ibusimcontext,
186ff6
+                             gboolean       do_connect)
186ff6
+{
186ff6
+    GtkWidget *widget = NULL;
186ff6
+
186ff6
+    g_assert (ibusimcontext->client_window);
186ff6
+    gdk_window_get_user_data (ibusimcontext->client_window,
186ff6
+                              (gpointer *)&widget);
186ff6
+    /* firefox needs GtkWidget instead of GtkWindow */
186ff6
+    if (GTK_IS_WIDGET (widget)) {
186ff6
+        if (do_connect) {
186ff6
+            g_signal_connect (
186ff6
+                    widget,
186ff6
+                    "button-press-event",
186ff6
+                    G_CALLBACK (ibus_im_context_button_press_event_cb),
186ff6
+                    ibusimcontext);
186ff6
+        } else {
186ff6
+            g_signal_handlers_disconnect_by_func (
186ff6
+                    widget,
186ff6
+                    G_CALLBACK (ibus_im_context_button_press_event_cb),
186ff6
+                    ibusimcontext);
186ff6
+        }
186ff6
+    }
186ff6
+}
186ff6
+#endif
186ff6
+
186ff6
 static void
186ff6
 ibus_im_context_set_client_window (GtkIMContext *context, GdkWindow *client)
186ff6
 {
186ff6
     IBusIMContext *ibusimcontext;
186ff6
-#if !GTK_CHECK_VERSION (3, 93, 0)
186ff6
-    GtkWidget *widget;
186ff6
-#endif
186ff6
 
186ff6
     IDEBUG ("%s", __FUNCTION__);
186ff6
 
186ff6
@@ -1138,15 +1165,8 @@ ibus_im_context_set_client_window (GtkIMContext *context, GdkWindow *client)
186ff6
 
186ff6
     if (ibusimcontext->client_window) {
186ff6
 #if !GTK_CHECK_VERSION (3, 93, 0)
186ff6
-        gdk_window_get_user_data (ibusimcontext->client_window,
186ff6
-                                  (gpointer *)&widget);
186ff6
-        /* firefox needs GtkWidget instead of GtkWindow */
186ff6
-        if (GTK_IS_WIDGET (widget)) {
186ff6
-            g_signal_handlers_disconnect_by_func (
186ff6
-                    widget,
186ff6
-                    (GCallback)ibus_im_context_button_press_event_cb,
186ff6
-                    ibusimcontext);
186ff6
-        }
186ff6
+        if (ibusimcontext->use_button_press_event)
186ff6
+            _connect_button_press_event (ibusimcontext, FALSE);
186ff6
 #endif
186ff6
         g_object_unref (ibusimcontext->client_window);
186ff6
         ibusimcontext->client_window = NULL;
186ff6
@@ -1155,17 +1175,8 @@ ibus_im_context_set_client_window (GtkIMContext *context, GdkWindow *client)
186ff6
     if (client != NULL) {
186ff6
         ibusimcontext->client_window = g_object_ref (client);
186ff6
 #if !GTK_CHECK_VERSION (3, 93, 0)
186ff6
-        gdk_window_get_user_data (ibusimcontext->client_window,
186ff6
-                                  (gpointer *)&widget);
186ff6
-
186ff6
-        /* firefox needs GtkWidget instead of GtkWindow */
186ff6
-        if (GTK_IS_WIDGET (widget)) {
186ff6
-            g_signal_connect (
186ff6
-                    widget,
186ff6
-                    "button-press-event",
186ff6
-                    G_CALLBACK (ibus_im_context_button_press_event_cb),
186ff6
-                    ibusimcontext);
186ff6
-        }
186ff6
+        if (ibusimcontext->use_button_press_event)
186ff6
+            _connect_button_press_event (ibusimcontext, TRUE);
186ff6
 #endif
186ff6
     }
186ff6
     if (ibusimcontext->slave)
186ff6
@@ -1631,6 +1642,15 @@ _ibus_context_update_preedit_text_cb (IBusInputContext  *ibuscontext,
186ff6
         ibusimcontext->preedit_attrs = NULL;
186ff6
     }
186ff6
 
186ff6
+    if (!ibusimcontext->use_button_press_event &&
186ff6
+        mode == IBUS_ENGINE_PREEDIT_COMMIT) {
186ff6
+#if !GTK_CHECK_VERSION (3, 93, 0)
186ff6
+        if (ibusimcontext->client_window)
186ff6
+            _connect_button_press_event (ibusimcontext, TRUE);
186ff6
+#endif
186ff6
+        ibusimcontext->use_button_press_event = TRUE;
186ff6
+    }
186ff6
+
186ff6
     str = text->text;
186ff6
     ibusimcontext->preedit_string = g_strdup (str);
186ff6
     if (text->attrs) {
186ff6
-- 
186ff6
2.19.1
186ff6