diff --git a/ibus-1385349-segv-bus-proxy.patch b/ibus-1385349-segv-bus-proxy.patch index 5f86a7b..a53b78c 100644 --- a/ibus-1385349-segv-bus-proxy.patch +++ b/ibus-1385349-segv-bus-proxy.patch @@ -1,6 +1,6 @@ -From f5790e1244fc6c83615ca4bc29494c7f16c73b6f Mon Sep 17 00:00:00 2001 +From db158389251d9360518abcbdd1770d0e82dbb855 Mon Sep 17 00:00:00 2001 From: fujiwarat -Date: Sun, 11 Jun 2023 20:20:06 +0900 +Date: Sun, 9 Jul 2023 19:04:44 +0900 Subject: [PATCH] Fix SEGV in bus_panel_proxy_focus_in() rhbz#1350291 SEGV in BUS_IS_CONNECTION(skip_connection) in @@ -285,7 +285,7 @@ index e6001ebf..00828fbc 100644 panel->panel_type = panel_type; return panel; diff --git a/client/x11/main.c b/client/x11/main.c -index 83d95cb7..804e40ed 100644 +index b7eb5961..3075d5d0 100644 --- a/client/x11/main.c +++ b/client/x11/main.c @@ -45,6 +45,7 @@ @@ -386,7 +386,7 @@ index 83d95cb7..804e40ed 100644 g_free (x11ic->preedit_string); x11ic->preedit_string = NULL; -@@ -438,6 +467,8 @@ xim_set_ic_focus (XIMS xims, IMChangeFocusStruct *call_data) +@@ -439,6 +468,8 @@ xim_set_ic_focus (XIMS xims, IMChangeFocusStruct *call_data) x11ic = (X11IC *) g_hash_table_lookup (_x11_ic_table, GINT_TO_POINTER ((gint) call_data->icid)); g_return_val_if_fail (x11ic != NULL, 0); @@ -395,7 +395,7 @@ index 83d95cb7..804e40ed 100644 ibus_input_context_focus_in (x11ic->context); _xim_set_cursor_location (x11ic); -@@ -456,6 +487,8 @@ xim_unset_ic_focus (XIMS xims, IMChangeFocusStruct *call_data) +@@ -458,6 +489,8 @@ xim_unset_ic_focus (XIMS xims, IMChangeFocusStruct *call_data) x11ic = (X11IC *) g_hash_table_lookup (_x11_ic_table, GINT_TO_POINTER ((gint) call_data->icid)); g_return_val_if_fail (x11ic != NULL, 0); @@ -404,16 +404,16 @@ index 83d95cb7..804e40ed 100644 ibus_input_context_focus_out (x11ic->context); -@@ -594,6 +627,8 @@ xim_forward_event (XIMS xims, IMForwardEventStruct *call_data) - x11ic = (X11IC *) g_hash_table_lookup (_x11_ic_table, - GINT_TO_POINTER ((gint) call_data->icid)); +@@ -712,6 +745,8 @@ xim_forward_event (XIMS xims, IMForwardEventStruct *call_data) + _x11_ic_table, + GINT_TO_POINTER ((gint) call_data->icid)); g_return_val_if_fail (x11ic != NULL, 0); + if (!x11ic->ibus_connected) + return 0; xevent = (XKeyEvent*) &(call_data->event); -@@ -836,6 +871,8 @@ _xim_set_cursor_location (X11IC *x11ic) +@@ -870,6 +905,8 @@ _xim_set_cursor_location (X11IC *x11ic) } } @@ -422,7 +422,7 @@ index 83d95cb7..804e40ed 100644 ibus_input_context_set_cursor_location (x11ic->context, preedit_area.x, preedit_area.y, -@@ -916,6 +953,8 @@ xim_reset_ic (XIMS xims, IMResetICStruct *call_data) +@@ -950,6 +987,8 @@ xim_reset_ic (XIMS xims, IMResetICStruct *call_data) x11ic = (X11IC *) g_hash_table_lookup (_x11_ic_table, GINT_TO_POINTER ((gint) call_data->icid)); g_return_val_if_fail (x11ic != NULL, 0); @@ -431,7 +431,7 @@ index 83d95cb7..804e40ed 100644 ibus_input_context_reset (x11ic->context); -@@ -1275,7 +1314,12 @@ _atexit_cb () +@@ -1309,7 +1348,12 @@ _atexit_cb () static void _sighandler (int sig) { @@ -611,5 +611,5 @@ index 9400e9ba..2ecbdac1 100644 #if VALA_0_34 seat.ungrab(); -- -2.40.0 +2.41.0 diff --git a/ibus-HEAD.patch b/ibus-HEAD.patch index 9f2ae56..fcbc386 100644 --- a/ibus-HEAD.patch +++ b/ibus-HEAD.patch @@ -2336,9 +2336,9 @@ index 68dde2f3..fee0b3ee 100644 -- 2.41.0 -From 8a1bd5ff72b7edf47526cfa19325f7e1dab85f59 Mon Sep 17 00:00:00 2001 +From a73ea2c335145cd5d00ebfade83204d055aa268c Mon Sep 17 00:00:00 2001 From: fujiwarat -Date: Fri, 7 Jul 2023 08:49:49 +0900 +Date: Sun, 9 Jul 2023 18:46:21 +0900 Subject: [PATCH 1/2] src: Fix sync ibus_input_context_process_key_event() The synchronous "ProcessKeyEvent" D-Bus method cannot receive @@ -2354,10 +2354,10 @@ method and ibus-daemon does not handle those signals. BUG=https://github.com/ibus/ibus/issues/2486 --- bus/inputcontext.c | 587 +++++++++++++++++++++++++++--------- - client/gtk2/ibusimcontext.c | 51 ++-- + client/gtk2/ibusimcontext.c | 225 ++++++++++---- src/ibusinputcontext.c | 162 +++++++++- src/ibusinputcontext.h | 30 +- - 4 files changed, 652 insertions(+), 178 deletions(-) + 4 files changed, 781 insertions(+), 223 deletions(-) diff --git a/bus/inputcontext.c b/bus/inputcontext.c index e76bbdfc..2110af87 100644 @@ -3658,7 +3658,7 @@ index e76bbdfc..2110af87 100644 GVariant *variant = ibus_serializable_serialize ( (IBusSerializable *)text); diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c -index ea8270bb..8ee85149 100644 +index ea8270bb..d57575ce 100644 --- a/client/gtk2/ibusimcontext.c +++ b/client/gtk2/ibusimcontext.c @@ -111,7 +111,7 @@ static guint _signal_delete_surrounding_id = 0; @@ -3670,10 +3670,35 @@ index ea8270bb..8ee85149 100644 #else static const gchar *_no_snooper_apps = NO_SNOOPER_APPS; static gboolean _use_key_snooper = ENABLE_SNOOPER; -@@ -386,6 +386,23 @@ typedef struct { +@@ -386,6 +386,7 @@ typedef struct { gboolean retval; } ProcessKeyEventReplyData; ++ + static void + _process_key_event_done (GObject *object, + GAsyncResult *res, +@@ -435,6 +436,7 @@ _process_key_event_done (GObject *object, + #endif + } + ++ + static void + _process_key_event_reply_done (GObject *object, + GAsyncResult *res, +@@ -457,6 +459,7 @@ _process_key_event_reply_done (GObject *object, + g_source_remove (data->count_cb_id); + } + ++ + static gboolean + _process_key_event_count_cb (gpointer user_data) + { +@@ -472,6 +475,101 @@ _process_key_event_count_cb (gpointer user_data) + return G_SOURCE_CONTINUE; + } + ++ +static gboolean +_process_key_event_sync (IBusInputContext *context, + guint keyval, @@ -3691,10 +3716,87 @@ index ea8270bb..8ee85149 100644 + return retval; +} + - static void - _process_key_event_done (GObject *object, - GAsyncResult *res, -@@ -505,10 +522,7 @@ _process_key_event (IBusInputContext *context, ++ ++static gboolean ++_process_key_event_async (IBusInputContext *context, ++ guint keyval, ++ guint keycode, ++ guint state, ++ GdkEvent *event, ++ IBusIMContext *ibusimcontext) ++{ ++ ProcessKeyEventData *data = g_slice_new0 (ProcessKeyEventData); ++ ++ g_assert (event); ++ if (!data) { ++ g_warning ("Cannot allocate async data"); ++ return _process_key_event_sync (context, keyval, keycode, state); ++ } ++#if GTK_CHECK_VERSION (3, 98, 4) ++ data->event = gdk_event_ref (event); ++#else ++ data->event = gdk_event_copy (event); ++#endif ++ data->ibusimcontext = ibusimcontext; ++ ibus_input_context_process_key_event_async (context, ++ keyval, ++ keycode - 8, ++ state, ++ -1, ++ NULL, ++ _process_key_event_done, ++ data); ++ ++ return TRUE; ++} ++ ++ ++static gboolean ++_process_key_event_hybrid_async (IBusInputContext *context, ++ guint keyval, ++ guint keycode, ++ guint state) ++{ ++ GSource *source = g_timeout_source_new (1); ++ ProcessKeyEventReplyData *data = NULL; ++ gboolean retval = FALSE; ++ ++ if (source) ++ data = g_slice_new0 (ProcessKeyEventReplyData); ++ if (!data) { ++ g_warning ("Cannot wait for the reply of the process key event."); ++ retval = _process_key_event_sync (context, keyval, keycode, state); ++ if (source) ++ g_source_destroy (source); ++ return retval; ++ } ++ data->count = 1; ++ g_source_attach (source, NULL); ++ g_source_unref (source); ++ data->count_cb_id = g_source_get_id (source); ++ ibus_input_context_process_key_event_async (context, ++ keyval, ++ keycode - 8, ++ state, ++ -1, ++ NULL, ++ _process_key_event_reply_done, ++ data); ++ g_source_set_callback (source, _process_key_event_count_cb, data, NULL); ++ while (data->count) ++ g_main_context_iteration (NULL, TRUE); ++ /* #2498 Checking source->ref_count might cause Nautilus hang up ++ */ ++ retval = data->retval; ++ g_slice_free (ProcessKeyEventReplyData, data); ++ return retval; ++} ++ ++ + static gboolean + _process_key_event (IBusInputContext *context, + #if GTK_CHECK_VERSION (3, 98, 4) +@@ -505,70 +603,20 @@ _process_key_event (IBusInputContext *context, switch (_use_sync_mode) { case 1: { @@ -3706,53 +3808,131 @@ index ea8270bb..8ee85149 100644 break; } case 2: { -@@ -519,10 +533,7 @@ _process_key_event (IBusInputContext *context, - data = g_slice_new0 (ProcessKeyEventReplyData); - if (!data) { - g_warning ("Cannot wait for the reply of the process key event."); +- GSource *source = g_timeout_source_new (1); +- ProcessKeyEventReplyData *data = NULL; +- +- if (source) +- data = g_slice_new0 (ProcessKeyEventReplyData); +- if (!data) { +- g_warning ("Cannot wait for the reply of the process key event."); - retval = ibus_input_context_process_key_event (context, - keyval, - keycode - 8, - state); -+ retval = _process_key_event_sync (context, keyval, keycode, state); - if (source) - g_source_destroy (source); - break; -@@ -542,17 +553,19 @@ _process_key_event (IBusInputContext *context, - g_source_set_callback (source, _process_key_event_count_cb, data, NULL); - while (data->count) - g_main_context_iteration (NULL, TRUE); +- if (source) +- g_source_destroy (source); +- break; +- } +- data->count = 1; +- g_source_attach (source, NULL); +- g_source_unref (source); +- data->count_cb_id = g_source_get_id (source); +- ibus_input_context_process_key_event_async (context, +- keyval, +- keycode - 8, +- state, +- -1, +- NULL, +- _process_key_event_reply_done, +- data); +- g_source_set_callback (source, _process_key_event_count_cb, data, NULL); +- while (data->count) +- g_main_context_iteration (NULL, TRUE); - if (source->ref_count > 0) { - /* g_source_get_id() could causes a SEGV */ - g_info ("Broken GSource.ref_count and maybe a timing issue in %p.", - source); - } -+ /* #2498 Checking source->ref_count might cause Nautilus hang up -+ */ - retval = data->retval; - g_slice_free (ProcessKeyEventReplyData, data); +- retval = data->retval; +- g_slice_free (ProcessKeyEventReplyData, data); ++ retval = _process_key_event_hybrid_async (context, ++ keyval, keycode, state); break; } default: { - ProcessKeyEventData *data = g_slice_new0 (ProcessKeyEventData); -+ if (!data) { -+ g_warning ("Cannot allocate async data"); -+ retval = _process_key_event_sync (context, keyval, keycode, state); -+ break; -+ } - #if GTK_CHECK_VERSION (3, 98, 4) - data->event = gdk_event_ref (event); - #else -@@ -877,7 +890,7 @@ ibus_im_context_class_init (IBusIMContextClass *class) +- ProcessKeyEventData *data = g_slice_new0 (ProcessKeyEventData); +-#if GTK_CHECK_VERSION (3, 98, 4) +- data->event = gdk_event_ref (event); +-#else +- data->event = gdk_event_copy ((GdkEvent *)event); +-#endif +- data->ibusimcontext = ibusimcontext; +- ibus_input_context_process_key_event_async (context, +- keyval, +- keycode - 8, +- state, +- -1, +- NULL, +- _process_key_event_done, +- data); +- +- retval = TRUE; ++ retval = _process_key_event_async (context, ++ keyval, keycode, state, ++ (GdkEvent *)event, ++ ibusimcontext); ++ break; + } + } + +@@ -877,7 +925,55 @@ ibus_im_context_class_init (IBusIMContextClass *class) g_assert (_signal_retrieve_surrounding_id != 0); #if GTK_CHECK_VERSION (3, 98, 4) - _use_sync_mode = _get_char_env ("IBUS_ENABLE_SYNC_MODE", 2); ++ /* IBus GtkIMModule, QtIMModlue, ibus-x11, ibus-wayland are called as ++ * IBus clients. ++ * Each GTK application, each QT application, Xorg server, Wayland ++ * comppsitor are called as IBus event owners here. ++ * ++ * The IBus client processes the key events between the IBus event owner ++ * and the IBus daemon and the procedure step is to: ++ * ++ * receive the key event from the IBus event owner and forward the ++ * event to the IBus daemon with the "ProcessKeyEvent" D-Bus method at ++ * first, ++ * ++ * receive the return value from the IBus daemon with the "ProessKeyEvent" ++ * D-Bus method and forward the value to the IBus event owner secondly and ++ * the return value includes if the key event is processed normally or not. ++ * ++ * The procedure behavior can be changed by the "IBUS_ENABLE_SYNC_MODE" ++ * environment variable with the synchronous procedure or asynchronous ++ * one and value is: ++ * ++ * 1: Synchronous process key event: ++ * Wait for the return of the IBus "ProcessKeyEvent" D-Bus method ++ * synchronously and forward the return value to the IBus event owner ++ * synchronously. ++ * 0: Asynchronous process key event: ++ * Return to the IBus event owner as the key event is processed normally ++ * at first as soon as the IBus client receives the event from the ++ * IBus event owner and also forward the event to the IBus daemon with ++ * the "ProcessKeyEvent" D-Bus method and wait for the return value of ++ * the D-Bus method *asynchronously*. ++ * If the return value indicates the key event is disposed by IBus, ++ * the IBus client does not perform anything. Otherwise the IBus client ++ * forwards the key event with the gdk_event_put() in GTK3, ++ * gtk_im_context_filter_key() in GTK4, IMForwardEvent() in XIM API. ++ * 2: Hybrid asynchronous process key event: ++ * Wait for the return of the IBus "ProcessKeyEvent" D-Bus method ++ * *asynchronously* with a GSource loop and forward the return value ++ * to the IBus event owner synchronously. So IBus clients perform ++ * virtually synchronously to cover problems of IBus synchronous APIs. ++ * ++ * The purpose of the asynchronous process is that each IBus input ++ * method can process the key events without D-Bus timeout and also ++ * the IBus synchronous process has a problem that the IBus ++ * "ProcessKeyEvent" D-Bus method cannot send the commit-text and ++ * forwar-key-event D-Bus signals until the D-Bus method is finished. ++ * ++ * Relative issues: #1713, #2486 ++ */ + _use_sync_mode = _get_char_env ("IBUS_ENABLE_SYNC_MODE", 1); #else _use_key_snooper = !_get_boolean_env ("IBUS_DISABLE_SNOOPER", !(ENABLE_SNOOPER)); -@@ -1004,8 +1017,6 @@ ibus_im_context_init (GObject *obj) +@@ -1004,8 +1100,6 @@ ibus_im_context_init (GObject *obj) #else ibusimcontext->caps = IBUS_CAP_PREEDIT_TEXT | IBUS_CAP_FOCUS; #endif @@ -3761,15 +3941,16 @@ index ea8270bb..8ee85149 100644 ibusimcontext->events_queue = g_queue_new (); -@@ -2265,6 +2276,7 @@ _create_input_context_done (IBusBus *bus, +@@ -2265,6 +2359,8 @@ _create_input_context_done (IBusBus *bus, else { gboolean requested_surrounding_text = FALSE; ibus_input_context_set_client_commit_preedit (context, TRUE); -+ ibus_input_context_set_post_process_key_event (context, TRUE); ++ if (_use_sync_mode == 1) ++ ibus_input_context_set_post_process_key_event (context, TRUE); ibusimcontext->ibuscontext = context; g_signal_connect (ibusimcontext->ibuscontext, -@@ -2489,9 +2501,8 @@ _create_fake_input_context_done (IBusBus *bus, +@@ -2489,9 +2585,8 @@ _create_fake_input_context_done (IBusBus *bus, G_CALLBACK (_ibus_fake_context_destroy_cb), NULL); @@ -4061,23 +4242,23 @@ index 09992148..1cb5126a 100644 -- 2.41.0 -From 1092bfa619749a931d65f80ec49e93b7b31f60f5 Mon Sep 17 00:00:00 2001 +From dd7e85890ced5e53d982f02f5b11ef5a36e2eab8 Mon Sep 17 00:00:00 2001 From: fujiwarat -Date: Fri, 7 Jul 2023 08:52:51 +0900 +Date: Sun, 9 Jul 2023 18:48:21 +0900 Subject: [PATCH 2/2] client/x11: Fix sync ibus_input_context_process_key_event() Fix the synchronous "ProcessKeyEvent" D-Bus method in ibus-x11 too. -Fixes: https://github.com/ibus/ibus/commit/8a1bd5f +Fixes: https://github.com/ibus/ibus/commit/a73ea2c BUG=https://github.com/ibus/ibus/issues/2486 --- - client/x11/main.c | 104 ++++++++++++++++++++++++---------------------- - 1 file changed, 54 insertions(+), 50 deletions(-) + client/x11/main.c | 234 ++++++++++++++++++++++++++-------------------- + 1 file changed, 134 insertions(+), 100 deletions(-) diff --git a/client/x11/main.c b/client/x11/main.c -index 83d95cb7..13e7a1cf 100644 +index 83d95cb7..b7eb5961 100644 --- a/client/x11/main.c +++ b/client/x11/main.c @@ -126,7 +126,7 @@ static gint g_debug_level = 0; @@ -4089,27 +4270,77 @@ index 83d95cb7..13e7a1cf 100644 static void _xim_preedit_start (XIMS xims, const X11IC *x11ic) -@@ -380,9 +380,8 @@ xim_create_ic (XIMS xims, IMChangeICStruct *call_data) +@@ -380,9 +380,9 @@ xim_create_ic (XIMS xims, IMChangeICStruct *call_data) if (x11ic->input_style & XIMPreeditCallbacks) capabilities |= IBUS_CAP_PREEDIT_TEXT; - if (_use_sync_mode == 1) - capabilities |= IBUS_CAP_SYNC_PROCESS_KEY_V2; ibus_input_context_set_capabilities (x11ic->context, capabilities); -+ ibus_input_context_set_post_process_key_event (x11ic->context, TRUE); ++ if (_use_sync_mode == 1) ++ ibus_input_context_set_post_process_key_event (x11ic->context, TRUE); g_hash_table_insert (_x11_ic_table, GINT_TO_POINTER (x11ic->icid), (gpointer)x11ic); -@@ -498,6 +497,26 @@ typedef struct { +@@ -427,6 +427,7 @@ xim_destroy_ic (XIMS xims, IMChangeICStruct *call_data) + return 1; + } + ++ + static int + xim_set_ic_focus (XIMS xims, IMChangeFocusStruct *call_data) + { +@@ -445,6 +446,7 @@ xim_set_ic_focus (XIMS xims, IMChangeFocusStruct *call_data) + return 1; + } + ++ + static int + xim_unset_ic_focus (XIMS xims, IMChangeFocusStruct *call_data) + { +@@ -463,6 +465,7 @@ xim_unset_ic_focus (XIMS xims, IMChangeFocusStruct *call_data) + + } + ++ + static void + _xim_forward_key_event_done (X11IC *x11ic, + XEvent *event, +@@ -498,6 +501,7 @@ typedef struct { XEvent event; } ProcessKeyEventReplyData; -+static gboolean ++ + static void + _process_key_event_done (GObject *object, + GAsyncResult *res, +@@ -529,6 +533,7 @@ _process_key_event_done (GObject *object, + g_slice_free (ProcessKeyEventReplyData, data); + } + ++ + static void + _process_key_event_reply_done (GObject *object, + GAsyncResult *res, +@@ -566,6 +571,7 @@ _process_key_event_reply_done (GObject *object, + g_source_remove (data->count_cb_id); + } + ++ + static gboolean + _process_key_event_count_cb (gpointer user_data) + { +@@ -580,19 +586,131 @@ _process_key_event_count_cb (gpointer user_data) + return G_SOURCE_CONTINUE; + } + ++ ++static int +_process_key_event_sync (X11IC *x11ic, + IMForwardEventStruct *call_data, + GdkEventKey *event) +{ -+ gboolean retval = FALSE; ++ gboolean retval; + + g_assert (x11ic); + g_assert (call_data); @@ -4121,16 +4352,125 @@ index 83d95cb7..13e7a1cf 100644 + event->state); + ibus_input_context_post_process_key_event (x11ic->context); + _xim_forward_key_event_done (x11ic, &call_data->event, retval); -+ return TRUE; ++ return 1; +} + - static void - _process_key_event_done (GObject *object, - GAsyncResult *res, -@@ -609,14 +628,7 @@ xim_forward_event (XIMS xims, IMForwardEventStruct *call_data) ++ ++static int ++_process_key_event_async (X11IC *x11ic, ++ IMForwardEventStruct *call_data, ++ GdkEventKey *event) ++{ ++ ProcessKeyEventReplyData *data; ++ ++ g_assert (x11ic); ++ g_assert (call_data); ++ g_assert (event); ++ if (!(data = g_slice_new0 (ProcessKeyEventReplyData))) { ++ g_warning ("Cannot allocate async data"); ++ return _process_key_event_sync (x11ic, call_data, event); ++ } ++ data->connect_id = call_data->connect_id; ++ data->x11ic = x11ic; ++ data->event = call_data->event; ++ ibus_input_context_process_key_event_async (x11ic->context, ++ event->keyval, ++ event->hardware_keycode - 8, ++ event->state, ++ -1, ++ NULL, ++ _process_key_event_done, ++ data); ++ return 1; ++} ++ ++ ++static int ++_process_key_event_hybrid_async (X11IC *x11ic, ++ IMForwardEventStruct *call_data, ++ GdkEventKey *event) ++{ ++ GSource *source; ++ ProcessKeyEventReplyData *data = NULL; ++ gboolean bus_retval; ++ ++ g_assert (x11ic); ++ g_assert (call_data); ++ g_assert (event); ++ source = g_timeout_source_new (1); ++ if (source) ++ data = g_slice_new0 (ProcessKeyEventReplyData); ++ if (!data) { ++ int xim_retval; ++ g_warning ("Cannot wait for the reply of the process key event."); ++ xim_retval = _process_key_event_sync (x11ic, call_data, event); ++ if (source) ++ g_source_destroy (source); ++ return xim_retval; ++ } ++ data->count = 1; ++ g_source_attach (source, NULL); ++ g_source_unref (source); ++ data->count_cb_id = g_source_get_id (source); ++ data->connect_id = call_data->connect_id; ++ data->x11ic = x11ic; ++ data->event = call_data->event; ++ ibus_input_context_process_key_event_async (x11ic->context, ++ event->keyval, ++ event->hardware_keycode - 8, ++ event->state, ++ -1, ++ NULL, ++ _process_key_event_reply_done, ++ data); ++ g_source_set_callback (source, _process_key_event_count_cb, ++ data, NULL); ++ while (data->count > 0 && data->count < MAX_WAIT_KEY_TIME) ++ g_main_context_iteration (NULL, TRUE); ++ /* #2498 Checking source->ref_count might cause Nautilus hang up ++ */ ++ bus_retval = data->retval; ++ if (data->count == 0) { ++ g_slice_free (ProcessKeyEventReplyData, data); ++ return 1; ++ } ++ ++ g_slice_free (ProcessKeyEventReplyData, data); ++ if (g_hash_table_lookup (_connections, ++ GINT_TO_POINTER ((gint)call_data->connect_id)) ++ == NULL) { ++ return 1; ++ } ++ _xim_forward_key_event_done (x11ic, &call_data->event, bus_retval); ++ return 1; ++} ++ ++ + static int + xim_forward_event (XIMS xims, IMForwardEventStruct *call_data) + { + X11IC *x11ic; + XKeyEvent *xevent; + GdkEventKey event; +- gboolean retval; + + LOG (1, "XIM_FORWARD_EVENT ic=%d connect_id=%d", +- call_data->icid, call_data->connect_id); ++ call_data->icid, call_data->connect_id); + +- x11ic = (X11IC *) g_hash_table_lookup (_x11_ic_table, +- GINT_TO_POINTER ((gint) call_data->icid)); ++ x11ic = (X11IC *) g_hash_table_lookup ( ++ _x11_ic_table, ++ GINT_TO_POINTER ((gint) call_data->icid)); + g_return_val_if_fail (x11ic != NULL, 0); + + xevent = (XKeyEvent*) &(call_data->event); +@@ -608,99 +726,15 @@ xim_forward_event (XIMS xims, IMForwardEventStruct *call_data) + } switch (_use_sync_mode) { - case 1: { +- case 1: { - retval = ibus_input_context_process_key_event ( - x11ic->context, - event.keyval, @@ -4139,22 +4479,22 @@ index 83d95cb7..13e7a1cf 100644 - _xim_forward_key_event_done (x11ic, &call_data->event, retval); - retval = 1; - break; -+ return _process_key_event_sync (x11ic, call_data, &event); - } - case 2: { - GSource *source = g_timeout_source_new (1); -@@ -626,44 +638,37 @@ xim_forward_event (XIMS xims, IMForwardEventStruct *call_data) - data = g_slice_new0 (ProcessKeyEventReplyData); - if (!data) { - g_warning ("Cannot wait for the reply of the process key event."); +- } +- case 2: { +- GSource *source = g_timeout_source_new (1); +- ProcessKeyEventReplyData *data = NULL; +- +- if (source) +- data = g_slice_new0 (ProcessKeyEventReplyData); +- if (!data) { +- g_warning ("Cannot wait for the reply of the process key event."); - retval = ibus_input_context_process_key_event ( - x11ic->context, - event.keyval, - event.hardware_keycode - 8, - event.state); -+ retval = _process_key_event_sync (x11ic, call_data, &event); - if (source) - g_source_destroy (source); +- if (source) +- g_source_destroy (source); - } else { - data->count = 1; - g_source_attach (source, NULL); @@ -4186,48 +4526,55 @@ index 83d95cb7..13e7a1cf 100644 - g_slice_free (ProcessKeyEventReplyData, data); - return 1; - } -+ break; -+ } -+ data->count = 1; -+ g_source_attach (source, NULL); -+ g_source_unref (source); -+ data->count_cb_id = g_source_get_id (source); -+ data->connect_id = call_data->connect_id; -+ data->x11ic = x11ic; -+ data->event = *((XEvent*)xevent); -+ ibus_input_context_process_key_event_async ( -+ x11ic->context, -+ event.keyval, -+ event.hardware_keycode - 8, -+ event.state, -+ -1, -+ NULL, -+ _process_key_event_reply_done, -+ data); -+ g_source_set_callback (source, _process_key_event_count_cb, -+ data, NULL); -+ while (data->count > 0 && data->count < MAX_WAIT_KEY_TIME) -+ g_main_context_iteration (NULL, TRUE); -+ /* #2498 Checking source->ref_count might cause Nautilus hang up -+ */ -+ retval = data->retval; -+ if (data->count == 0) { -+ g_slice_free (ProcessKeyEventReplyData, data); -+ return 1; - } - - g_slice_free (ProcessKeyEventReplyData, data); -@@ -681,8 +686,7 @@ xim_forward_event (XIMS xims, IMForwardEventStruct *call_data) - - if (!(data = g_slice_new0 (ProcessKeyEventReplyData))) { - g_warning ("Cannot allocate async data"); +- } +- +- g_slice_free (ProcessKeyEventReplyData, data); +- if (g_hash_table_lookup (_connections, +- GINT_TO_POINTER ((gint)call_data->connect_id)) +- == NULL) { +- return 1; +- } +- _xim_forward_key_event_done (x11ic, &call_data->event, retval); +- retval = 1; +- break; +- } +- default: { +- ProcessKeyEventReplyData *data; +- +- if (!(data = g_slice_new0 (ProcessKeyEventReplyData))) { +- g_warning ("Cannot allocate async data"); - _xim_forward_key_event_done (x11ic, &call_data->event, 0); - return 1; -+ return _process_key_event_sync (x11ic, call_data, &event); - } - data->connect_id = call_data->connect_id; - data->x11ic = x11ic; -@@ -1186,7 +1190,7 @@ _init_ibus (void) +- } +- data->connect_id = call_data->connect_id; +- data->x11ic = x11ic; +- data->event = call_data->event; +- +- ibus_input_context_process_key_event_async ( +- x11ic->context, +- event.keyval, +- event.hardware_keycode - 8, +- event.state, +- -1, +- NULL, +- _process_key_event_done, +- data); +- retval = 1; +- } ++ case 1: ++ return _process_key_event_sync (x11ic, call_data, &event); ++ case 2: ++ return _process_key_event_hybrid_async (x11ic, call_data, &event); ++ default: ++ return _process_key_event_async (x11ic, call_data, &event); + } +- return retval; ++ g_assert_not_reached (); ++ return 0; + } + + +@@ -1186,7 +1220,7 @@ _init_ibus (void) G_CALLBACK (_bus_disconnected_cb), NULL); /* https://github.com/ibus/ibus/issues/1713 */ diff --git a/ibus.spec b/ibus.spec index c59529a..8b73f26 100644 --- a/ibus.spec +++ b/ibus.spec @@ -50,7 +50,7 @@ Name: ibus Version: 1.5.28 -Release: 11%{?dist} +Release: 12%{?dist} Summary: Intelligent Input Bus for Linux OS License: LGPL-2.0-or-later URL: https://github.com/ibus/%name/wiki @@ -557,6 +557,9 @@ dconf update || : %{_datadir}/installed-tests/ibus %changelog +* Sun Jul 09 2023 Takao Fujiwara - 1.5.28-12 +- Fix sync ibus_input_context_process_key_event() #2 + * Fri Jul 07 2023 Takao Fujiwara - 1.5.28-11 - Fix sync ibus_input_context_process_key_event()