Blob Blame History Raw
commit 1ddfdc1219586ed7ca11bed38827b38dacd88aef
Author: Choe Hwanjin <choe.hwanjin@gmail.com>
Date:   Sat Dec 31 01:04:22 2016 +0900

    Fix wrong space order problem
    
    With IBUS_ENABLE_SYNC_MODE=1 option,
    'rksk ' is translated '가 나'.
    It's caused by limitations of IBus implementation.
    IBus can not send a result of other function inside a function
    in sync mode. The results of other functions will be delayed until
    the current function ends.
    This makes ibus-hangul do wrong.
    
    We solve this problem by forwarding key event.
    It may be a hack, but we can not help it.
    That's the limitation of the framework.
    
    https://github.com/choehwanjin/ibus-hangul/issues/42

diff --git a/src/engine.c b/src/engine.c
index bd009cb..960bedc 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -1190,7 +1190,54 @@ ibus_hangul_engine_process_key_event (IBusEngine     *engine,
             ibus_hangul_engine_flush (hangul);
     }
 
-    return retval;
+    /* We always return TRUE here even if we didn't use this event.
+     * Instead, we forward the event to clients.
+     *
+     * Because IBus has a problem with sync mode.
+     * I think it's limitations of IBus implementation.
+     * We call several engine functions(updating preedit text and committing
+     * text) inside this function.
+     * But clients cannot receive the results of other calls until this
+     * function ends. Clients only get one result from a remote call at a time
+     * because clients may run on event loop.
+     * Clients may process this event first and then get the results which
+     * may change the preedit text or commit text.
+     * So the event order is broken.
+     * Call order:
+     *      engine                          client
+     *                                      call process_key_event
+     *      begin process_key_event
+     *        call commit_text
+     *        call update_preedit_text
+     *      return the event as unused
+     *                                      receive the result of process_key_event
+     *                                      receive the result of commit_text
+     *                                      receive the result of update_preedit_text
+     *
+     * To solve this problem, we return TRUE as if we consumed this event.
+     * After that, we forward this event to clients.
+     * Then clients may get the events in correct order.
+     * This approach is a kind of async processing.
+     * Call order:
+     *      engine                          client
+     *                                      call process_key_event
+     *      begin process_key_event
+     *        call commit_text
+     *        call update_preedit_text
+     *        call forward_key_event
+     *      return the event as used
+     *                                      receive the result of process_key_event
+     *                                      receive the result of commit_text
+     *                                      receive the result of update_preedit_text
+     *                                      receive the forwarded key event
+     *
+     * See: https://github.com/choehwanjin/ibus-hangul/issues/40
+     */
+    if (!retval) {
+        ibus_engine_forward_key_event (engine, keyval, keycode, modifiers);
+    }
+
+    return TRUE;
 }
 
 static void