package scim
severity 434180 important
tags 434180 + confirmed
thanks

On Sun, Jul 22, 2007 at 04:45:58PM +0800, manphiz wrote:
> 
> Seems further investigation is required.

CHOE Hwanjin posted a patch/workaround for scim to the upstream mailing
list [1].  So far there is no response yet, but it won't hurt to test.

1. http://www.scim-im.org/forums/scim_devel#nabble-to14503465

I'll attach the patch.  I've built a package with this patch applied, so
far it doesn't seem to break anything.  I'll need more time to see if it
indeed fixes the bug.  After that I need more testing from other users,
especially to see if it plays nicely with deadkeys.

Ming
2008.02.02
Index: modules/FrontEnd/IMdkit/i18nPtHdr.c
===================================================================
--- modules/FrontEnd/IMdkit/i18nPtHdr.c	(revision 56)
+++ modules/FrontEnd/IMdkit/i18nPtHdr.c	(working copy)
@@ -53,6 +53,38 @@
 
 extern Xi18nClient *_Xi18nFindClient (Xi18n, CARD16);
 
+static void DiscardQueue (XIMS ims, CARD16 connect_id)
+{
+    Xi18n i18n_core = ims->protocol;
+    Xi18nClient *client = (Xi18nClient *) _Xi18nFindClient (i18n_core,
+                                                            connect_id);
+
+    if (client != NULL) {
+	client->sync = False;
+	while (client->pending != NULL) {
+	    XIMPending* pending = client->pending;
+
+	    client->pending = pending->next;
+
+	    XFree(pending->p);
+	    XFree(pending);
+	}
+    }
+}
+
+static void DiscardAllQueue(XIMS ims)
+{
+    Xi18n i18n_core = ims->protocol;
+    Xi18nClient* client = i18n_core->address.clients;
+
+    while (client != NULL) {
+	if (client->sync) {
+	    DiscardQueue(ims, client->connect_id);
+	}
+	client = client->next;
+    }
+}
+
 static void GetProtocolVersion (CARD16 client_major,
                                 CARD16 client_minor,
                                 CARD16 *server_major,
@@ -866,6 +898,21 @@
     CARD16 connect_id = call_data->any.connect_id;
     CARD16 input_method_ID;
 
+    /* some buggy xim clients do not send XIM_SYNC_REPLY for synchronous
+     * events. In such case, xim server is waiting for XIM_SYNC_REPLY 
+     * forever. So the xim server is blocked to waiting sync reply. 
+     * It prevents further input.
+     * Usually it happens when a client calls XSetICFocus() with another ic 
+     * before passing an event to XFilterEvent(), where the event is needed
+     * by the old focused ic to sync its state.
+     * To avoid such problem, remove the whole clients queue and set them 
+     * as asynchronous.
+     *
+     * See:
+     * http://bugs.freedesktop.org/show_bug.cgi?id=7869
+     */
+    DiscardAllQueue(ims);
+
     setfocus = (IMChangeFocusStruct *) &call_data->changefocus;
 
     fm = FrameMgrInit (set_ic_focus_fr,
@@ -897,7 +944,18 @@
     IMChangeFocusStruct *unsetfocus;
     CARD16 connect_id = call_data->any.connect_id;
     CARD16 input_method_ID;
+    Xi18nClient *client = _Xi18nFindClient (i18n_core, connect_id);
 
+    /* some buggy clients unset focus ic before the ic answer the sync reply,
+     * so the xim server may be blocked to waiting sync reply. To avoid 
+     * this problem, remove the client queue and set it asynchronous
+     * 
+     * See: SetICFocusMessageProc
+     */
+    if (client != NULL && client->sync) {
+	DiscardQueue(ims, client->connect_id);
+    }
+
     unsetfocus = (IMChangeFocusStruct *) &call_data->changefocus;
 
     fm = FrameMgrInit (unset_ic_focus_fr,

Reply via email to