public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/ibus] autotool: Detect mouse click to commit Hangul preedit
@ 2026-05-31  2:07 Takao Fujiwara
  0 siblings, 0 replies; only message in thread
From: Takao Fujiwara @ 2026-05-31  2:07 UTC (permalink / raw)
  To: git-commits

            A new commit has been pushed.

            Repo   : rpms/ibus
            Branch : autotool
            Commit : ec5ba95d77b5786ce871d9a3ad0b6abbd459625e
            Author : Takao Fujiwara <tfujiwar@redhat.com>
            Date   : 2018-11-15T14:42:36+09:00
            Stats  : +804/-1 in 2 file(s)
            URL    : https://src.fedoraproject.org/rpms/ibus/c/ec5ba95d77b5786ce871d9a3ad0b6abbd459625e?branch=autotool

            Log:
            Detect mouse click to commit Hangul preedit

- Do not delete IBUS_CAP_SURROUNDING_TEXT

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

diff --git a/ibus.spec b/ibus.spec
index 5f68349..2178ef7 100644
--- a/ibus.spec
+++ b/ibus.spec
@@ -31,7 +31,7 @@
 
 Name:           ibus
 Version:        1.5.19
-Release:        8%{?dist}
+Release:        9%{?dist}
 Summary:        Intelligent Input Bus for Linux OS
 License:        LGPLv2+
 Group:          System Environment/Libraries
@@ -240,6 +240,7 @@ The ibus-devel-docs package contains developer documentation for IBus
 %prep
 %autosetup -S git
 # cp client/gtk2/ibusimcontext.c client/gtk3/ibusimcontext.c || :
+cp client/gtk2/ibusimcontext.c client/gtk3/ibusimcontext.c || :
 
 zcat %SOURCE3 | tar xfv -
 
@@ -425,6 +426,10 @@ dconf update || :
 %{_datadir}/gtk-doc/html/*
 
 %changelog
+* Thu Nov 15 2018 Takao Fujiwara <tfujiwar@redhat.com> - 1.5.19-9
+- Detect mouse click to commit Hangul preedit
+- Do not delete IBUS_CAP_SURROUNDING_TEXT
+
 * Tue Nov 06 2018 Takao Fujiwara <tfujiwar@redhat.com> - 1.5.19-8
 - Reverted noarch for devel-docs by mistake
 

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-05-31  2:07 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-05-31  2:07 [rpms/ibus] autotool: Detect mouse click to commit Hangul preedit Takao Fujiwara

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox