diff --git a/ibus-HEAD.patch b/ibus-HEAD.patch index e69de29..aab0eba 100644 --- a/ibus-HEAD.patch +++ b/ibus-HEAD.patch @@ -0,0 +1,374 @@ +From 9d9dca9e103e88b33e786c4a46f44123a6cf11c6 Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Wed, 8 Mar 2023 19:44:16 +0900 +Subject: [PATCH] client/x11: Fix Key typing order + +ibus-x11 now also uses the hybrid process key events with +IBUS_ENABLE_SYNC_MODE=2 and it waits for the async API +with GSource and g_main_context_iteration() in xim_forward_event(). + +But g_main_context_iteration() calls gdk_event_source_dispatch() +and it can call another xim_forward_event() and the callbacks +of ibus_input_context_process_key_event_async() can be nested. +So if the forwarding API is called out of the callbacks of +ibus_input_context_process_key_event_async(), the key events +order is swapped due to the delayed return of +g_main_context_iteration(). + +To resolve this issue, the forwarding API should be called in +the callbacks of ibus_input_context_process_key_event_async(). + +BUG=https://github.com/ibus/ibus/issues/2480 +--- + client/x11/main.c | 160 ++++++++++++++++++++++++---------------------- + 1 file changed, 83 insertions(+), 77 deletions(-) + +diff --git a/client/x11/main.c b/client/x11/main.c +index 905fd251..83d95cb7 100644 +--- a/client/x11/main.c ++++ b/client/x11/main.c +@@ -2,7 +2,7 @@ + /* vim:set et sts=4: */ + /* ibus + * Copyright (C) 2007-2015 Peng Huang +- * Copyright (C) 2015-2022 Takao Fujiwara ++ * Copyright (C) 2015-2023 Takao Fujiwara + * Copyright (C) 2007-2015 Red Hat, Inc. + * + * main.c: +@@ -49,6 +49,8 @@ + #include + + #define ESC_SEQUENCE_ISO10646_1 "\033%G" ++/* Wait for about 120 secs to return a key from async process-key-event. */ ++#define MAX_WAIT_KEY_TIME 120000 + + #define LOG(level, fmt_args...) \ + if (g_debug_level >= (level)) { \ +@@ -461,11 +463,39 @@ xim_unset_ic_focus (XIMS xims, IMChangeFocusStruct *call_data) + + } + ++static void ++_xim_forward_key_event_done (X11IC *x11ic, ++ XEvent *event, ++ gboolean processed) ++{ ++ IMForwardEventStruct fe; ++ if (processed) { ++ if (!x11ic->has_preedit_area) { ++ _xim_set_cursor_location (x11ic); ++ } ++ return; ++ } ++ g_assert (x11ic); ++ g_assert (event); ++ ++ memset (&fe, 0, sizeof (fe)); ++ fe.major_code = XIM_FORWARD_EVENT; ++ fe.icid = x11ic->icid; ++ fe.connect_id = x11ic->connect_id; ++ fe.sync_bit = 0; ++ fe.serial_number = 0L; ++ fe.event = *event; ++ IMForwardEvent (_xims, (XPointer) &fe); ++} ++ ++ + typedef struct { +- IMForwardEventStruct *pfe; + int count; + guint count_cb_id; + gboolean retval; ++ X11IC *x11ic; ++ CARD16 connect_id; ++ XEvent event; + } ProcessKeyEventReplyData; + + static void +@@ -474,7 +504,7 @@ _process_key_event_done (GObject *object, + gpointer user_data) + { + IBusInputContext *context = (IBusInputContext *)object; +- IMForwardEventStruct *pfe = (IMForwardEventStruct*) user_data; ++ ProcessKeyEventReplyData *data = (ProcessKeyEventReplyData *)user_data; + + GError *error = NULL; + gboolean retval = ibus_input_context_process_key_event_async_finish ( +@@ -488,16 +518,15 @@ _process_key_event_done (GObject *object, + } + + if (g_hash_table_lookup (_connections, +- GINT_TO_POINTER ((gint) pfe->connect_id)) ++ GINT_TO_POINTER ((gint)data->connect_id)) + == NULL) { +- g_slice_free (IMForwardEventStruct, pfe); ++ g_slice_free (ProcessKeyEventReplyData, data); + return; + } + +- if (retval == FALSE) { +- IMForwardEvent (_xims, (XPointer) pfe); +- } +- g_slice_free (IMForwardEventStruct, pfe); ++ if (retval == FALSE) ++ _xim_forward_key_event_done (data->x11ic, &data->event, retval); ++ g_slice_free (ProcessKeyEventReplyData, data); + } + + static void +@@ -518,6 +547,21 @@ _process_key_event_reply_done (GObject *object, + } + g_return_if_fail (data); + data->retval = retval; ++ if (g_hash_table_lookup (_connections, ++ GINT_TO_POINTER ((gint)data->connect_id)) ++ == NULL) { ++ return; ++ } ++ /* _xim_forward_key_event_done() should be called in ++ * _process_key_event_reply_done() because g_main_context_iteration() ++ * can call another xim_forward_event() and xim_forward_event() can be ++ * nested and the first _process_key_event_reply_done() is returned ++ * at last with g_main_context_iteration() so ++ * if _xim_forward_key_event_done() is called out of ++ * _process_key_event_reply_done(), the key events order ++ * can be swapped. ++ */ ++ _xim_forward_key_event_done (data->x11ic, &data->event, retval); + data->count = 0; + g_source_remove (data->count_cb_id); + } +@@ -529,9 +573,8 @@ _process_key_event_count_cb (gpointer user_data) + g_return_val_if_fail (data, G_SOURCE_REMOVE); + if (!data->count) + return G_SOURCE_REMOVE; +- /* Wait for about 10 secs. */ +- if (data->count++ == 10000) { +- data->count = 0; ++ if (data->count++ == MAX_WAIT_KEY_TIME) { ++ g_warning ("Key event is not returned for %usecs.", MAX_WAIT_KEY_TIME); + return G_SOURCE_REMOVE; + } + return G_SOURCE_CONTINUE; +@@ -571,32 +614,13 @@ xim_forward_event (XIMS xims, IMForwardEventStruct *call_data) + event.keyval, + event.hardware_keycode - 8, + event.state); +- if (retval) { +- if (!x11ic->has_preedit_area) { +- _xim_set_cursor_location (x11ic); +- } +- return 1; +- } +- +- IMForwardEventStruct fe; +- memset (&fe, 0, sizeof (fe)); +- +- fe.major_code = XIM_FORWARD_EVENT; +- fe.icid = x11ic->icid; +- fe.connect_id = x11ic->connect_id; +- fe.sync_bit = 0; +- fe.serial_number = 0L; +- fe.event = call_data->event; +- +- IMForwardEvent (_xims, (XPointer) &fe); +- ++ _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; +- IMForwardEventStruct fe; + + if (source) + data = g_slice_new0 (ProcessKeyEventReplyData); +@@ -610,11 +634,13 @@ xim_forward_event (XIMS xims, IMForwardEventStruct *call_data) + if (source) + g_source_destroy (source); + } else { +- CARD16 connect_id = x11ic->connect_id; + 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, +@@ -626,7 +652,7 @@ xim_forward_event (XIMS xims, IMForwardEventStruct *call_data) + data); + g_source_set_callback (source, _process_key_event_count_cb, + data, NULL); +- while (data->count) ++ 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 */ +@@ -634,46 +660,33 @@ xim_forward_event (XIMS xims, IMForwardEventStruct *call_data) + "issue in %p.", source); + } + retval = data->retval; +- g_slice_free (ProcessKeyEventReplyData, data); +- +- if (g_hash_table_lookup (_connections, +- GINT_TO_POINTER ((gint)connect_id)) +- == NULL) { ++ if (data->count == 0) { ++ g_slice_free (ProcessKeyEventReplyData, data); + return 1; + } + } + +- if (retval) { +- if (! x11ic->has_preedit_area) { +- _xim_set_cursor_location (x11ic); +- } +- return 1; ++ g_slice_free (ProcessKeyEventReplyData, data); ++ if (g_hash_table_lookup (_connections, ++ GINT_TO_POINTER ((gint)call_data->connect_id)) ++ == NULL) { ++ return 1; + } +- +- memset (&fe, 0, sizeof (fe)); +- +- fe.major_code = XIM_FORWARD_EVENT; +- fe.icid = x11ic->icid; +- fe.connect_id = x11ic->connect_id; +- fe.sync_bit = 0; +- fe.serial_number = 0L; +- fe.event = call_data->event; +- +- IMForwardEvent (_xims, (XPointer) &fe); +- ++ _xim_forward_key_event_done (x11ic, &call_data->event, retval); + retval = 1; + break; + } + default: { +- IMForwardEventStruct *pfe; ++ ProcessKeyEventReplyData *data; + +- pfe = g_slice_new0 (IMForwardEventStruct); +- pfe->major_code = XIM_FORWARD_EVENT; +- pfe->icid = x11ic->icid; +- pfe->connect_id = x11ic->connect_id; +- pfe->sync_bit = 0; +- pfe->serial_number = 0L; +- pfe->event = call_data->event; ++ 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, +@@ -683,7 +696,7 @@ xim_forward_event (XIMS xims, IMForwardEventStruct *call_data) + -1, + NULL, + _process_key_event_done, +- pfe); ++ data); + retval = 1; + } + } +@@ -962,11 +975,10 @@ _xim_forward_key_event (X11IC *x11ic, + guint keycode, + guint state) + { +- g_return_if_fail (x11ic != NULL); +- +- IMForwardEventStruct fe = {0}; + XEvent xkp = {0}; + ++ g_return_if_fail (x11ic != NULL); ++ + xkp.xkey.type = (state & IBUS_RELEASE_MASK) ? KeyRelease : KeyPress; + xkp.xkey.serial = 0L; + xkp.xkey.send_event = False; +@@ -975,20 +987,14 @@ _xim_forward_key_event (X11IC *x11ic, + xkp.xkey.window = + x11ic->focus_window ? x11ic->focus_window : x11ic->client_window; + xkp.xkey.subwindow = None; +- xkp.xkey.root = DefaultRootWindow (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ())); ++ xkp.xkey.root = DefaultRootWindow ( ++ GDK_DISPLAY_XDISPLAY (gdk_display_get_default ())); + + xkp.xkey.time = 0; + xkp.xkey.state = state; + xkp.xkey.keycode = (keycode == 0) ? 0 : keycode + 8; + +- fe.major_code = XIM_FORWARD_EVENT; +- fe.icid = x11ic->icid; +- fe.connect_id = x11ic->connect_id; +- fe.sync_bit = 0; +- fe.serial_number = 0L; +- fe.event = xkp; +- +- IMForwardEvent (_xims, (XPointer) & fe); ++ _xim_forward_key_event_done (x11ic, &xkp, FALSE); + } + + static void +-- +2.38.1 + +From 5b5d0795f297e330fdc84b6be6beab1305b0cda9 Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Wed, 15 Mar 2023 10:22:05 +0900 +Subject: [PATCH] util/IMdkit: Disable while loop before call + ForwardEventMessageProc() + +Seems ProcessQueue() had a wrong XFree() with async process-key-event. +Fixes: c0fec89ae76f9522319f58107ab234992b249ec6 + +BUG=https://github.com/ibus/ibus/issues/2484 +--- + util/IMdkit/i18nPtHdr.c | 9 +++------ + 1 file changed, 3 insertions(+), 6 deletions(-) + +diff --git a/util/IMdkit/i18nPtHdr.c b/util/IMdkit/i18nPtHdr.c +index 8dc52714..ec20e322 100644 +--- a/util/IMdkit/i18nPtHdr.c ++++ b/util/IMdkit/i18nPtHdr.c +@@ -1747,11 +1747,13 @@ static void ProcessQueue (XIMS ims, CARD16 connect_id) + XimProtoHdr *hdr = (XimProtoHdr *) client->pending->p; + unsigned char *p1 = (unsigned char *) (hdr + 1); + IMProtocol call_data; ++ XIMPending *old = client->pending; + + call_data.major_code = hdr->major_opcode; + call_data.any.minor_code = hdr->minor_opcode; + call_data.any.connect_id = connect_id; + ++ client->pending = old->next; + switch (hdr->major_opcode) + { + case XIM_FORWARD_EVENT: +@@ -1760,12 +1762,7 @@ static void ProcessQueue (XIMS ims, CARD16 connect_id) + } + /*endswitch*/ + XFree (hdr); +- { +- XIMPending *old = client->pending; +- +- client->pending = old->next; +- XFree (old); +- } ++ XFree (old); + } + /*endwhile*/ + return; +-- +2.39.2 + diff --git a/ibus.spec b/ibus.spec index 8a4d764..57fd194 100644 --- a/ibus.spec +++ b/ibus.spec @@ -50,7 +50,7 @@ Name: ibus Version: 1.5.28 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Intelligent Input Bus for Linux OS License: LGPL-2.0-or-later URL: https://github.com/ibus/%name/wiki @@ -58,6 +58,7 @@ Source0: https://github.com/ibus/%name/releases/download/%{version}/%{nam Source1: %{name}-xinput Source2: %{name}.conf.5 # Patch0: %%{name}-HEAD.patch +Patch0: %{name}-HEAD.patch # Under testing #1349148 #1385349 #1350291 #1406699 #1432252 #1601577 Patch1: %{name}-1385349-segv-bus-proxy.patch %if 0%{?fedora:0}%{?rhel:1} @@ -282,7 +283,8 @@ desktop testing runner internally. %package tests Summary: Tests for the %{name} package -Requires: %{name}%{?_isa} = %{version}-%{release} +Requires: %{name}%{?_isa} = %{version}-%{release} +Requires: %{name}-libs%{?_isa} = %{version}-%{release} %description tests The %{name}-tests package contains tests that can be used to verify @@ -555,6 +557,10 @@ dconf update || : %{_datadir}/installed-tests/ibus %changelog +* Wed Mar 15 2023 Takao Fujiwara - 1.5.28-2 +- Fix Key typing order in ibus-x11 +- Disable while loop before call ForwardEventMessageProc() in ibus-x11 + * Tue Feb 21 2023 Takao Fujiwara - 1.5.28-1 - Bump to 1.5.28