Comment #11 on issue 1419 by [email protected]: Were "enabled"/"disabled" signals and enable()/disable() methods accidentally removed?
http://code.google.com/p/ibus/issues/detail?id=1419

(1) Signal to track the change of engine

Currently ibus-mode has the handlers for "enalbled" and "disabled" signals in ibus-el-egent (which is a bridge between Emacs and ibus-daemon written in Python) as follows:

def enabled_cb(ic):
print '(ibus-status-changed-cb %d "%s")'%(ic.id_no, ic.get_engine().name)
    ic.surrouding_text_received = False

def disabled_cb(ic):
    print '(ibus-status-changed-cb %d nil)'%ic.id_no
    ic.surrouding_text_received = False

Here, ic is an object of IBusELInputContext class based on ibus.InputContext, and (ibus-status-changed-cb ...) is callback in Emacs-side which changes mode line, cursor color, and keymap according to engine's status. ibus-mode selects a suitable keymap from four different keymaps.

I forgot to say in the previous comments that changing the keymap is very important to distinguish backslash key (ろ) and yen-mark key (ー) in Japanese kana-typing.

If "engine-changed" signal is provided, ibus-mode can solve the incompatibility by simply adding one more signal handler like below:

def engine_changed_cb(ic):
    engine_name = ic.get_engine().name
    print '(ibus-status-changed-cb %d "%s")'% \
(ic.id_no, 'nil' if engine_name.startswith('xkb:layout:') else engine_name)
    ic.surrouding_text_received = False

If not, stupid modifications will be needed instead. A callback to check current engine periodically has to be added to IBusELInputContext class:

    def __init__(self, bus):
        ...
        self.prev_engine = None
        self.check_engine_cb_id = None

    def start_check_engine(self):
        if not self.check_engine_cb_id:
self.check_engine_cb_id = glib.timeout_add(1, self.check_engine_cb)

    def stop_check_engine(self):
        if self.check_engine_cb_id:
            glib.source_remove(self.check_engine_cb_id)
            self.check_engine_cb_id = None

    def check_engine_cb(self):
        engine = self.get_engine()
        if engine != self.prev_engine:
             engine_changed_cb(self)
             self.prev_engine = engine
        return True

start_check_engine() and stop_check_engine() should be called when inupt focus is changed.

Also, ic.check_engine_cb() defined above has to be called every time the methods such as process_key_event() are called.


(2) Methods to switch between IM and xkb

Currently ibus-el-agent has the following functions to enable/disable IM engine:

def enable(id_no):
    imcontexts[id_no].enable()

def disable(id_no):
    imcontexts[id_no].disable()

Here, imcontexts[] is an array of the input contexts for each buffer in Emacs.

We assume the new methods use_im() and use_xkb() will be added as substitutes for enable() and disable(), then the above functions can be modified as follows:

def enable(id_no):
    ic = imcontexts[id_no]
    try:
        ic.enable()
    except AttributeError:
        ic.use_im()

def disable(id_no):
    ic = imcontexts[id_no]
    try:
        ic.disable()
    except AttributeError:
        ic.use_xkb()

If such methods cannot be used, much complicated modifications are needed:

step 1.
   Obtain keybinding of trigger key as:

trigger = dict(bus.get_config().get_values('general/hotkey'))['trigger']

   and convert this result to (keyval, keycode, modmask)

step 2.
   Obtain which engine the input context currently used:

     engine = ic.get_engine()

step 3.
Call process_key_event(keyval, keycode, modmask) to send the trigger key if necessary

I cannot write such complicated code immediately.

I don't know another solution.


--
You received this message because you are subscribed to the Google
Groups "ibus-devel" group.
iBus project web page: http://code.google.com/p/ibus/
iBus dev group: http://groups.google.com/group/ibus-devel?hl=en

回复