public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
From: Takao Fujiwara <tfujiwar@redhat.com>
To: git-commits@fedoraproject.org
Subject: [rpms/ibus] autotool: Fix Key typing order in ibus-x11
Date: Sun, 31 May 2026 02:08:07 GMT	[thread overview]
Message-ID: <178019328720.1.18234127830042040817.rpms-ibus-49b039c60d4d@fedoraproject.org> (raw)

            A new commit has been pushed.

            Repo   : rpms/ibus
            Branch : autotool
            Commit : 49b039c60d4d531d96346094b74ade3ed838d0e8
            Author : Takao Fujiwara <tfujiwar@redhat.com>
            Date   : 2023-03-15T11:58:05+09:00
            Stats  : +382/-2 in 2 file(s)
            URL    : https://src.fedoraproject.org/rpms/ibus/c/49b039c60d4d531d96346094b74ade3ed838d0e8?branch=autotool

            Log:
            Fix Key typing order in ibus-x11

- Disable while loop before call ForwardEventMessageProc() in ibus-x11

---
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 <takao.fujiwara1@gmail.com>
+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 <shawn.p.huang@gmail.com>
+- * Copyright (C) 2015-2022 Takao Fujiwara <takao.fujiwara1@gmail.com>
++ * Copyright (C) 2015-2023 Takao Fujiwara <takao.fujiwara1@gmail.com>
+  * Copyright (C) 2007-2015 Red Hat, Inc.
+  *
+  * main.c:
+@@ -49,6 +49,8 @@
+ #include <getopt.h>
+ 
+ #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 <takao.fujiwara1@gmail.com>
+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 <tfujiwar@redhat.com> - 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 <tfujiwar@redhat.com> - 1.5.28-1
 - Bump to 1.5.28
 

                 reply	other threads:[~2026-05-31  2:08 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=178019328720.1.18234127830042040817.rpms-ibus-49b039c60d4d@fedoraproject.org \
    --to=tfujiwar@redhat.com \
    --cc=git-commits@fedoraproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox