diff --git a/bus/ibusimpl.c b/bus/ibusimpl.c
index 80f3acfbb..bbbb57702 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 4f98b849c..1b8e7adbb 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[] =
""
" "
+ /* properties */
+ " "
+ " \n"
/* methods */
" "
" "
@@ -273,6 +277,12 @@ static const gchar introspection_xml[] =
" "
" "
" "
+ " "
+ " "
+ " "
+ " "
+ " "
+ " "
" "
" "
" "
@@ -297,9 +307,6 @@ static const gchar introspection_xml[] =
" "
" "
" "
-
- /* properties */
- " "
" "
"";
@@ -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 a46d5c062..7105fff87 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
- * Copyright (C) 2017 Takao Fujiwara
- * Copyright (C) 2008-2014 Red Hat, Inc.
+ * Copyright (C) 2017-2018 Takao Fujiwara
+ * 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 e4de52d93..73a0eaec6 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
- * Copyright (C) 2015-2017 Takao Fujiwara
- * Copyright (C) 2008-2017 Red Hat, Inc.
+ * Copyright (C) 2015-2018 Takao Fujiwara
+ * 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 ae7048ad9..a809ef08f 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
- * Copyright (C) 2008-2013 Red Hat, Inc.
+ * Copyright (C) 2018 Takao Fujiwara
+ * 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 a77cf92f3..099921489 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
- * Copyright (C) 2008-2013 Red Hat, Inc.
+ * Copyright (C) 2018 Takao Fujiwara
+ * 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