Fix sync ibus_input_context_process_key_event() #2

This commit is contained in:
Takao Fujiwara 2023-07-09 19:24:21 +09:00
parent 25ad70d245
commit 38fc0edf90
3 changed files with 471 additions and 121 deletions

View File

@ -1,6 +1,6 @@
From f5790e1244fc6c83615ca4bc29494c7f16c73b6f Mon Sep 17 00:00:00 2001
From db158389251d9360518abcbdd1770d0e82dbb855 Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
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

View File

@ -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 <takao.fujiwara1@gmail.com>
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 <takao.fujiwara1@gmail.com>
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 */

View File

@ -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 <tfujiwar@redhat.com> - 1.5.28-12
- Fix sync ibus_input_context_process_key_event() #2
* Fri Jul 07 2023 Takao Fujiwara <tfujiwar@redhat.com> - 1.5.28-11
- Fix sync ibus_input_context_process_key_event()