public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/ibus] autotool: Add preedit D-Bus signals to PostProcessKeyEvent
@ 2026-05-31 2:08 Takao Fujiwara
0 siblings, 0 replies; only message in thread
From: Takao Fujiwara @ 2026-05-31 2:08 UTC (permalink / raw)
To: git-commits
A new commit has been pushed.
Repo : rpms/ibus
Branch : autotool
Commit : 1c5ffb1a7e11b85b2e1f0c16fc34b0322c929fd5
Author : Takao Fujiwara <tfujiwar@redhat.com>
Date : 2023-10-25T17:55:00+09:00
Stats : +518/-1 in 2 file(s)
URL : https://src.fedoraproject.org/rpms/ibus/c/1c5ffb1a7e11b85b2e1f0c16fc34b0322c929fd5?branch=autotool
Log:
Add preedit D-Bus signals to PostProcessKeyEvent
---
diff --git a/ibus-HEAD.patch b/ibus-HEAD.patch
index 3f3eae3..a72a0a4 100644
--- a/ibus-HEAD.patch
+++ b/ibus-HEAD.patch
@@ -1412,3 +1412,516 @@ index def23b25..c6a030fe 100644
--
2.41.0
+From ef0d29d8bf4e533c428b2cd9d3ee9fa42e9e20e7 Mon Sep 17 00:00:00 2001
+From: fujiwarat <takao.fujiwara1@gmail.com>
+Date: Wed, 25 Oct 2023 16:46:07 +0900
+Subject: [PATCH] src: Add preedit D-Bus signals to PostProcessKeyEvent
+
+ibus-hangul calls UpdatePreeditText signal during pressing Enter key
+to hide the current preedit text and this also causes the reorder issue
+in sync process-key-event and need to move the preedit signals
+to PostProcessKeyEvent.
+
+Also refactor PostProcessKeyEvent codes.
+
+Fixes: https://github.com/ibus/ibus/commit/38f09c6
+
+BUG=https://github.com/ibus/ibus/pull/2575
+---
+ bus/inputcontext.c | 176 +++++++++++++++++++++++++++--------------
+ src/ibusinputcontext.c | 162 +++++++++++++++++++++++++++++--------
+ 2 files changed, 248 insertions(+), 90 deletions(-)
+
+diff --git a/bus/inputcontext.c b/bus/inputcontext.c
+index 64430fe4..c914fbd2 100644
+--- a/bus/inputcontext.c
++++ b/bus/inputcontext.c
+@@ -48,11 +48,25 @@ struct _SetEngineByDescData {
+ };
+ typedef struct _SetEngineByDescData SetEngineByDescData;
+
++typedef struct _DeleteSurroundingData {
++ gint offset;
++ guint nchars;
++} DeleteSurroundingData;
++
+ typedef struct _SyncForwardingData {
+- gchar key;
+- IBusText *text;
++ char key;
++ IBusText *text;
+ } SyncForwardingData;
+
++typedef struct _SyncForwardingPreData {
++ char key;
++ IBusText *text;
++ union {
++ guint uints[3];
++ DeleteSurroundingData deleting;
++ } u;
++} SyncForwardingPreData;
++
+ struct _BusInputContext {
+ IBusService parent;
+
+@@ -943,6 +957,7 @@ _ic_process_key_event (BusInputContext *context,
+ */
+ g_dbus_method_invocation_return_value (invocation,
+ g_variant_new ("(b)", TRUE));
++ context->processing_key_event = FALSE;
+ return;
+ }
+ if (G_UNLIKELY (!context->has_focus)) {
+@@ -1005,6 +1020,7 @@ _ic_process_key_event (BusInputContext *context,
+ else {
+ g_dbus_method_invocation_return_value (invocation,
+ g_variant_new ("(b)", FALSE));
++ context->processing_key_event = FALSE;
+ }
+ }
+
+@@ -1654,6 +1670,71 @@ bus_input_context_service_set_property (IBusService *service,
+ }
+
+
++static gboolean
++bus_input_context_make_post_process_key_event (BusInputContext *context,
++ SyncForwardingPreData *pre_data)
++{
++ SyncForwardingData *data;
++ if (context->processing_key_event && g_queue_get_length (
++ context->queue_during_process_key_event) <= MAX_SYNC_DATA) {
++ if (g_queue_get_length (context->queue_during_process_key_event)
++ == MAX_SYNC_DATA) {
++ g_warning ("Exceed max number of post process_key_event data");
++ }
++ data = g_slice_new (SyncForwardingData);
++ data->key = pre_data->key;
++ switch (pre_data->key) {
++ case 'c':
++ data->text = g_object_ref (pre_data->text);
++ break;
++ case 'd':
++ data->text = ibus_text_new_from_printf (
++ "%d,%u",
++ pre_data->u.deleting.offset,
++ pre_data->u.deleting.nchars);
++ break;
++ case 'f':
++ data->text = ibus_text_new_from_printf ("%u,%u,%u",
++ pre_data->u.uints[0],
++ pre_data->u.uints[1],
++ pre_data->u.uints[2]);
++ break;
++ case 'h':
++ case 'r':
++ case 's':
++ data->text = ibus_text_new_from_static_string ("");
++ break;
++ case 'u':
++ case 'm':
++ data->text = g_object_ref (pre_data->text);
++ g_queue_push_tail (context->queue_during_process_key_event, data);
++ data = g_slice_new (SyncForwardingData);
++ data->key = pre_data->key;
++ if (pre_data->key == 'u') {
++ data->text = ibus_text_new_from_printf (
++ "%u,%u",
++ pre_data->u.uints[0],
++ pre_data->u.uints[1]);
++ } else {
++ data->text = ibus_text_new_from_printf (
++ "%u,%u,%u",
++ pre_data->u.uints[0],
++ pre_data->u.uints[1],
++ pre_data->u.uints[2]);
++ }
++ break;
++ default:
++ g_warning ("Type %c of SyncForwardingData is not supported",
++ pre_data->key);
++ g_slice_free (SyncForwardingData, data);
++ return FALSE;
++ }
++ g_queue_push_tail (context->queue_during_process_key_event, data);
++ return TRUE;
++ }
++ return FALSE;
++}
++
+ gboolean
+ bus_input_context_has_focus (BusInputContext *context)
+ {
+@@ -1893,6 +1974,9 @@ bus_input_context_show_preedit_text (BusInputContext *context,
+ }
+
+ if (PREEDIT_CONDITION) {
++ SyncForwardingPreData pre_data = { 's', };
++ if (bus_input_context_make_post_process_key_event (context, &pre_data))
++ return;
+ bus_input_context_emit_signal (context,
+ "ShowPreeditText",
+ NULL,
+@@ -1933,6 +2017,9 @@ bus_input_context_hide_preedit_text (BusInputContext *context,
+ }
+
+ if (PREEDIT_CONDITION) {
++ SyncForwardingPreData pre_data = { 'h', };
++ if (bus_input_context_make_post_process_key_event (context, &pre_data))
++ return;
+ bus_input_context_emit_signal (context,
+ "HidePreeditText",
+ NULL,
+@@ -2375,27 +2462,18 @@ _engine_forward_key_event_cb (BusEngineProxy *engine,
+ guint state,
+ BusInputContext *context)
+ {
++ SyncForwardingPreData pre_data = { 'f', };
++
+ g_assert (BUS_IS_ENGINE_PROXY (engine));
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+-
+ g_assert (context->engine == engine);
+ g_assert (context->queue_during_process_key_event);
+
+- if (context->processing_key_event && g_queue_get_length (
+- context->queue_during_process_key_event) <= MAX_SYNC_DATA) {
+- SyncForwardingData *data;
+- IBusText *text = ibus_text_new_from_printf ("%u,%u,%u",
+- keyval, keycode, state);
+- if (g_queue_get_length (context->queue_during_process_key_event)
+- == MAX_SYNC_DATA) {
+- g_warning ("Exceed max number of post process_key_event data");
+- }
+- data = g_slice_new (SyncForwardingData);
+- data->key = 'f';
+- data->text = text;
+- g_queue_push_tail (context->queue_during_process_key_event, data);
++ pre_data.u.uints[0] = keyval;
++ pre_data.u.uints[1] = keycode;
++ pre_data.u.uints[2] = state;
++ if (bus_input_context_make_post_process_key_event (context, &pre_data))
+ return;
+- }
+ bus_input_context_emit_signal (context,
+ "ForwardKeyEvent",
+ g_variant_new ("(uuu)",
+@@ -2415,26 +2493,16 @@ _engine_delete_surrounding_text_cb (BusEngineProxy *engine,
+ guint nchars,
+ BusInputContext *context)
+ {
++ SyncForwardingPreData pre_data = { 'd', };
++
+ g_assert (BUS_IS_ENGINE_PROXY (engine));
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+-
+ g_assert (context->engine == engine);
+
+- if (context->processing_key_event && g_queue_get_length (
+- context->queue_during_process_key_event) <= MAX_SYNC_DATA) {
+- SyncForwardingData *data;
+- IBusText *text = ibus_text_new_from_printf ("%d,%u",
+- offset_from_cursor, nchars);
+- if (g_queue_get_length (context->queue_during_process_key_event)
+- == MAX_SYNC_DATA) {
+- g_warning ("Exceed max number of sync process_key_event data");
+- }
+- data = g_slice_new (SyncForwardingData);
+- data->key = 'd';
+- data->text = g_object_ref (text);
+- g_queue_push_tail (context->queue_during_process_key_event, data);
++ pre_data.u.deleting.offset = offset_from_cursor;
++ pre_data.u.deleting.nchars = nchars;
++ if (bus_input_context_make_post_process_key_event (context, &pre_data))
+ return;
+- }
+ bus_input_context_emit_signal (context,
+ "DeleteSurroundingText",
+ g_variant_new ("(iu)",
+@@ -2452,25 +2520,14 @@ static void
+ _engine_require_surrounding_text_cb (BusEngineProxy *engine,
+ BusInputContext *context)
+ {
++ SyncForwardingPreData pre_data = { 'r', };
++
+ g_assert (BUS_IS_ENGINE_PROXY (engine));
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+-
+ g_assert (context->engine == engine);
+
+- if (context->processing_key_event && g_queue_get_length (
+- context->queue_during_process_key_event) <= MAX_SYNC_DATA) {
+- SyncForwardingData *data;
+- IBusText *text = ibus_text_new_from_static_string ("");
+- if (g_queue_get_length (context->queue_during_process_key_event)
+- == MAX_SYNC_DATA) {
+- g_warning ("Exceed max number of post process_key_event data");
+- }
+- data = g_slice_new (SyncForwardingData);
+- data->key = 'r';
+- data->text = text;
+- g_queue_push_tail (context->queue_during_process_key_event, data);
++ if (bus_input_context_make_post_process_key_event (context, &pre_data))
+ return;
+- }
+ bus_input_context_emit_signal (context,
+ "RequireSurroundingText",
+ NULL,
+@@ -3178,6 +3235,8 @@ bus_input_context_commit_text_use_extension (BusInputContext *context,
+ IBusText *text,
+ gboolean use_extension)
+ {
++ SyncForwardingPreData pre_data = { 'c', text, };
++
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+ g_assert (context->queue_during_process_key_event);
+
+@@ -3186,17 +3245,9 @@ bus_input_context_commit_text_use_extension (BusInputContext *context,
+
+ if (use_extension && context->emoji_extension) {
+ bus_panel_proxy_commit_text_received (context->emoji_extension, text);
+- } else if (context->processing_key_event && g_queue_get_length (
+- context->queue_during_process_key_event) <= MAX_SYNC_DATA) {
+- SyncForwardingData *data;
+- if (g_queue_get_length (context->queue_during_process_key_event)
+- == MAX_SYNC_DATA) {
+- g_warning ("Exceed max number of sync process_key_event data");
+- }
+- data = g_slice_new (SyncForwardingData);
+- data->key = 'c';
+- data->text = g_object_ref (text);
+- g_queue_push_tail (context->queue_during_process_key_event, data);
++ } else if (bus_input_context_make_post_process_key_event (context,
++ &pre_data)) {
++ return;
+ } else {
+ GVariant *variant = ibus_serializable_serialize (
+ (IBusSerializable *)text);
+@@ -3245,9 +3296,18 @@ bus_input_context_update_preedit_text (BusInputContext *context,
+ context->preedit_cursor_pos,
+ context->preedit_visible);
+ } else if (PREEDIT_CONDITION) {
++ SyncForwardingPreData pre_data = { 'u', context->preedit_text, };
+ GVariant *variant = ibus_serializable_serialize (
+ (IBusSerializable *)context->preedit_text);
+- if (context->client_commit_preedit) {
++ pre_data.u.uints[0] = context->preedit_cursor_pos;
++ pre_data.u.uints[1] = extension_visible ? 1 : 0;
++ pre_data.u.uints[2] = context->preedit_mode;
++ if (context->client_commit_preedit)
++ pre_data.key = 'm';
++ if (bus_input_context_make_post_process_key_event (context,
++ &pre_data)) {
++ return;
++ } else if (context->client_commit_preedit) {
+ bus_input_context_emit_signal (
+ context,
+ "UpdatePreeditTextWithMode",
+diff --git a/src/ibusinputcontext.c b/src/ibusinputcontext.c
+index c6a030fe..1b62f656 100644
+--- a/src/ibusinputcontext.c
++++ b/src/ibusinputcontext.c
+@@ -1403,10 +1403,104 @@ ibus_input_context_set_post_process_key_event (IBusInputContext *context,
+ g_variant_unref (var_post);
+ }
+
++
++static void
++ibus_input_context_fwd_text_to_commit (IBusInputContext *context,
++ IBusText *text)
++{
++ g_signal_emit (context, context_signals[COMMIT_TEXT], 0, text);
++}
++
++
++static void
++ibus_input_context_fwd_text_to_forward_key_event (IBusInputContext *context,
++ IBusText *text)
++{
++ gchar **array = NULL;
++ guint keyval, keycode, state;
++ array = g_strsplit (text->text, ",", -1);
++ keyval = g_ascii_strtoull (array[0], NULL, 10);
++ keycode = g_ascii_strtoull (array[1], NULL, 10);
++ state = g_ascii_strtoull (array[2], NULL, 10);
++ g_strfreev (array);
++ g_signal_emit (context,
++ context_signals[FORWARD_KEY_EVENT],
++ 0,
++ keyval,
++ keycode,
++ state | IBUS_FORWARD_MASK);
++}
++
++
++static void
++ibus_input_context_fwd_text_to_require_surrounding (IBusInputContext *context,
++ IBusText *text)
++{
++ IBusInputContextPrivate *priv;
++ g_assert (IBUS_IS_INPUT_CONTEXT (context));
++ priv = IBUS_INPUT_CONTEXT_GET_PRIVATE (IBUS_INPUT_CONTEXT (context));
++ priv->needs_surrounding_text = TRUE;
++ g_signal_emit (context, context_signals[REQUIRE_SURROUNDING_TEXT], 0);
++}
++
++
++static void
++ibus_input_context_fwd_text_to_delete_surrounding (IBusInputContext *context,
++ IBusText *text)
++{
++ gchar **array = NULL;
++ gint offset_from_cursor;
++ guint nchars;
++ array = g_strsplit (text->text, ",", -1);
++ offset_from_cursor = g_ascii_strtoll (array[0], NULL, 10);
++ nchars = g_ascii_strtoull (array[1], NULL, 10);
++ g_strfreev (array);
++ g_signal_emit (context,
++ context_signals[DELETE_SURROUNDING_TEXT],
++ 0,
++ offset_from_cursor,
++ nchars);
++}
++
++
++static void
++ibus_input_context_fwd_text_to_update_preedit (IBusInputContext *context,
++ IBusText *text,
++ IBusText *position,
++ char type)
++{
++ gchar **array = NULL;
++ guint32 cursor_pos;
++ gboolean visible;
++ guint mode = 0;
++
++ array = g_strsplit (position->text, ",", -1);
++ cursor_pos = g_ascii_strtoull (array[0], NULL, 10);
++ visible = g_ascii_strtoull (array[1], NULL, 10) ? TRUE : FALSE;
++ if (type == 'u') {
++ g_signal_emit (context,
++ context_signals[UPDATE_PREEDIT_TEXT],
++ 0,
++ text,
++ cursor_pos,
++ visible);
++ } else {
++ mode = g_ascii_strtoull (array[2], NULL, 10);
++ g_signal_emit (context,
++ context_signals[UPDATE_PREEDIT_TEXT_WITH_MODE],
++ 0,
++ text,
++ cursor_pos,
++ visible,
++ mode);
++ }
++ g_strfreev (array);
++}
++
++
+ void
+ ibus_input_context_post_process_key_event (IBusInputContext *context)
+ {
+- IBusInputContextPrivate *priv;
+ GVariant *cached_var_post;
+ gboolean enable = FALSE;
+ GVariant *result;
+@@ -1419,7 +1513,6 @@ ibus_input_context_post_process_key_event (IBusInputContext *context)
+
+ g_assert (IBUS_IS_INPUT_CONTEXT (context));
+
+- priv = IBUS_INPUT_CONTEXT_GET_PRIVATE (IBUS_INPUT_CONTEXT (context));
+ cached_var_post =
+ g_dbus_proxy_get_cached_property ((GDBusProxy *)context,
+ "EffectivePostProcessKeyEvent");
+@@ -1454,7 +1547,7 @@ ibus_input_context_post_process_key_event (IBusInputContext *context)
+ g_assert (variant);
+ g_variant_iter_init (&iter, variant);
+ size = g_variant_iter_n_children (&iter);
+- while (size >0 && g_variant_iter_loop (&iter, "(yv)", &type, &vtext)) {
++ while (size > 0 && g_variant_iter_loop (&iter, "(yv)", &type, &vtext)) {
+ IBusText *text =
+ (IBusText *)ibus_serializable_deserialize_object (vtext);
+ if (!IBUS_IS_TEXT (text)) {
+@@ -1463,43 +1556,48 @@ ibus_input_context_post_process_key_event (IBusInputContext *context)
+ }
+ switch (type) {
+ case 'c':
+- g_signal_emit (context, context_signals[COMMIT_TEXT], 0, text);
++ ibus_input_context_fwd_text_to_commit (context, text);
+ break;
+ case 'f': {
+- gchar **array = NULL;
+- guint keyval, keycode, state;
+- array = g_strsplit (text->text, ",", -1);
+- keyval = g_ascii_strtoull (array[0], NULL, 10);
+- keycode = g_ascii_strtoull (array[1], NULL, 10);
+- state = g_ascii_strtoull (array[2], NULL, 10);
+- g_strfreev (array);
+- g_signal_emit (context,
+- context_signals[FORWARD_KEY_EVENT],
+- 0,
+- keyval,
+- keycode,
+- state | IBUS_FORWARD_MASK);
++ ibus_input_context_fwd_text_to_forward_key_event (context, text);
+ break;
+ }
+ case 'r': {
+- priv->needs_surrounding_text = TRUE;
+- g_signal_emit (context,
+- context_signals[REQUIRE_SURROUNDING_TEXT], 0);
++ ibus_input_context_fwd_text_to_require_surrounding (context, text);
+ break;
+ }
+ case 'd': {
+- gchar **array = NULL;
+- gint offset_from_cursor;
+- guint nchars;
+- array = g_strsplit (text->text, ",", -1);
+- offset_from_cursor = g_ascii_strtoll (array[0], NULL, 10);
+- nchars = g_ascii_strtoull (array[1], NULL, 10);
+- g_strfreev (array);
+- g_signal_emit (context,
+- context_signals[DELETE_SURROUNDING_TEXT],
+- 0,
+- offset_from_cursor,
+- nchars);
++ ibus_input_context_fwd_text_to_delete_surrounding (context, text);
++ break;
++ }
++ case 'u':
++ case 'm': {
++ IBusText *position;
++ g_clear_pointer (&vtext, g_variant_unref);
++ if (!g_variant_iter_loop (&iter, "(yv)", &type, &vtext)) {
++ g_warning ("%s: %s", G_STRFUNC,
++ "Type 'u' requires next type 'u'");
++ break;
++ }
++ if (type != 'u' && type != 'm') {
++ g_warning ("%s: %s", G_STRFUNC,
++ "The next of type 'u' should be type 'u'");
++ break;
++ }
++ position =
++ (IBusText *)ibus_serializable_deserialize_object (vtext);
++ if (!IBUS_IS_TEXT (position)) {
++ g_warning ("%s: %s", G_STRFUNC, "text is not IBusText");
++ break;
++ }
++ ibus_input_context_fwd_text_to_update_preedit (context,
++ text,
++ position,
++ type);
++ if (g_object_is_floating (position)) {
++ g_object_ref_sink (position);
++ g_object_unref (position);
++ }
+ break;
+ }
+ default:
+--
+2.41.0
+
diff --git a/ibus.spec b/ibus.spec
index 428a934..839ddec 100644
--- a/ibus.spec
+++ b/ibus.spec
@@ -58,7 +58,7 @@
Name: ibus
Version: 1.5.29~rc1
-Release: 5%{?dist}
+Release: 6%{?dist}
Summary: Intelligent Input Bus for Linux OS
License: LGPL-2.1-or-later
URL: https://github.com/ibus/%name/wiki
@@ -257,6 +257,7 @@ This package contains IBus IM module for Wayland
%package panel
Summary: IBus Panel icon
Requires: %{name}%{?_isa} = %{version}-%{release}
+Requires: %{name}-libs%{?_isa} = %{version}-%{release}
BuildRequires: libdbusmenu-gtk3-devel
%description panel
@@ -579,6 +580,9 @@ dconf update || :
%{_datadir}/installed-tests/ibus
%changelog
+* Wed Oct 25 2023 Takao Fujiwara <tfujiwar@redhat.com> - 1.5.29~rc1-6
+- Add preedit D-Bus signals to PostProcessKeyEvent
+
* Mon Oct 23 2023 Takao Fujiwara <tfujiwar@redhat.com> - 1.5.29~rc1-5
- Add DeleteSurroundingText to PostProcessKeyEvent
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-05-31 2:08 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:08 [rpms/ibus] autotool: Add preedit D-Bus signals to PostProcessKeyEvent Takao Fujiwara
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox