Fix sync ibus_input_context_process_key_event() #2
This commit is contained in:
parent
25ad70d245
commit
38fc0edf90
@ -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
|
||||
|
||||
|
563
ibus-HEAD.patch
563
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 <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 */
|
||||
|
@ -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()
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user