File ibus-sync-ibus_input_context_process_key_event_X11.patch of Package ibus
From 7502abbe7eb4289d0d727e53cdfac572baf405d5 Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Wed, 12 Jul 2023 07:52:21 +0900
Subject: [PATCH] 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/38f09c6
BUG=https://github.com/ibus/ibus/issues/2486
---
--- a/client/x11/main.c
+++ b/client/x11/main.c
@@ -126,7 +126,7 @@
static IBusBus *_bus = NULL;
-static char _use_sync_mode = 2;
+static char _use_sync_mode = 1;
static void
_xim_preedit_start (XIMS xims, const X11IC *x11ic)
@@ -380,9 +380,9 @@
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);
+ 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);
@@ -584,18 +584,126 @@
}
static int
+_process_key_event_sync (X11IC *x11ic,
+ IMForwardEventStruct *call_data,
+ GdkEventKey *event)
+{
+ gboolean retval;
+
+ g_assert (x11ic);
+ g_assert (call_data);
+ g_assert (event);
+ retval = ibus_input_context_process_key_event (
+ x11ic->context,
+ event->keyval,
+ event->hardware_keycode - 8,
+ event->state);
+ ibus_input_context_post_process_key_event (x11ic->context);
+ _xim_forward_key_event_done (x11ic, &call_data->event, retval);
+ return 1;
+}
+
+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);
@@ -611,99 +719,15 @@
}
switch (_use_sync_mode) {
- case 1: {
- retval = ibus_input_context_process_key_event (
- x11ic->context,
- event.keyval,
- event.hardware_keycode - 8,
- event.state);
- _xim_forward_key_event_done (x11ic, &call_data->event, retval);
- retval = 1;
- break;
- }
- 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);
- if (source)
- g_source_destroy (source);
- } else {
- 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);
- 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);
- }
- 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, 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;
- }
- 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;
}
@@ -1189,7 +1213,7 @@
G_CALLBACK (_bus_disconnected_cb), NULL);
/* https://github.com/ibus/ibus/issues/1713 */
- _use_sync_mode = _get_char_env ("IBUS_ENABLE_SYNC_MODE", 2);
+ _use_sync_mode = _get_char_env ("IBUS_ENABLE_SYNC_MODE", 1);
}
static void