IBus
IBus
- 以 D-Bus 架構實做的輸入法架構
- 不使用預設的 system bus 或 session bus, 另外用一個專屬的 bus 供元件之間的溝通使用。
- IBus 包含了以下幾個元件:
- IBus daemon (ibus-daemon): 主要服務入口
- IBus client: 使用輸入法的應用程式
- Engine: 輸入法的 object
- Input context: Client 不會直接跟 engine 溝通,而是透過 input context。每個 client 會用幾個 input context 不一定,例如 GNOME terminal 是每個終端機就使用一個 context,Chromium 58 是一個視窗用一個 context,Firefox 53 是每個視窗兩個 context (猜測可能是 UI 元件一個,網頁輸入元件一個)。
- Factory: 每次切換輸入法時,IBus 都會產生一個新的 engine,而製造 engine 的稱為 factory。原則上每種輸入法有一個 factory,但也有像 xkb (simple) 是一個 factory 製造所有 layout (xkb:us::eng, xkb:us:dvorak:eng, ...) 的 engine。
- Panel 是 IBus 的 UI 部份(比如說以「語言條」來呈現),通常是由桌面環境(如 GNOME, KDE, Unity, etc.)提供實做。Panel 包含了:
- Pre-edit text: 當前組字內容,常常以內嵌在內容視窗來呈現
- Auxiliary text: 可用來顯示組字狀態等等
- Lookup table: 選字表
- Properties: 按鈕或選單
- Config: 提供儲存設定的服務
- IBus daemon 產生的 bus address 寫在 $HOME/.config/ibus/bus/XXXXXXXXX-unix-0 這個檔案中,範例:
# This file is created by ibus-daemon, please do not modify it IBUS_ADDRESS=unix:abstract=/tmp/ibus/dbus-gj4mSVu0,guid=4bdac399fc305e7075c6bccc59159fe6 IBUS_DAEMON_PID=13344
- IBus daemon 位在 bus name: org.freedesktop.IBus,object path: /org/freedesktop/IBus,主要的 interface 是 org.freedesktop.IBus:
<interface name="org.freedesktop.IBus"> <method name="CreateInputContext"> <arg type="s" name="client_name" direction="in"/> <arg type="o" name="object_path" direction="out"/> </method> <method name="RegisterComponent"> <arg type="v" name="component" direction="in"/> </method> <method name="GetEnginesByNames"> <arg type="as" name="names" direction="in"/> <arg type="av" name="engines" direction="out"/> </method> <method name="Exit"> <arg type="b" name="restart" direction="in"/> </method> <method name="Ping"> <arg type="v" name="data" direction="in"/> <arg type="v" name="data" direction="out"/> </method> <method name="SetGlobalEngine"> <arg type="s" name="engine_name" direction="in"/> </method> <method name="GetAddress"> <annotation name="org.freedesktop.DBus.Deprecated" value="true"/> <arg type="s" name="address" direction="out"/> </method> <method name="CurrentInputContext"> <annotation name="org.freedesktop.DBus.Deprecated" value="true"/> <arg type="o" name="object_path" direction="out"/> </method> <method name="ListEngines"> <annotation name="org.freedesktop.DBus.Deprecated" value="true"/> <arg type="av" name="engines" direction="out"/> </method> <method name="ListActiveEngines"> <annotation name="org.freedesktop.DBus.Deprecated" value="true"/> <arg type="av" name="engines" direction="out"/> </method> <method name="GetUseSysLayout"> <annotation name="org.freedesktop.DBus.Deprecated" value="true"/> <arg type="b" name="enabled" direction="out"/> </method> <method name="GetUseGlobalEngine"> <arg type="b" name="enabled" direction="out"/> </method> <method name="IsGlobalEngineEnabled"> <annotation name="org.freedesktop.DBus.Deprecated" value="true"/> <arg type="b" name="enabled" direction="out"/> </method> <method name="GetGlobalEngine"> <annotation name="org.freedesktop.DBus.Deprecated" value="true"/> <arg type="v" name="desc" direction="out"/> </method> <signal name="RegistryChanged"/> <signal name="GlobalEngineChanged"> <arg type="s" name="engine_name"/> </signal> <property type="s" name="Address" access="read"/> <property type="o" name="CurrentInputContext" access="read"/> <property type="av" name="Engines" access="read"/> <property type="v" name="GlobalEngine" access="read"/> <property type="as" name="PreloadEngines" access="write"> <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="true"/> </property> <property type="b" name="EmbedPreeditText" access="readwrite"> <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="true"/> </property> <property type="av" name="ActiveEngines" access="read"/> </interface>
- Client 透過 input context 跟 engine 溝通。Client 呼叫 IBus daemon 的 CreateInputContext method 來產生 input context,並回傳該 context 的 object path (bus name 跟 IBus daemon 相同)。Input context 的主要 interface 是 org.freedesktop.IBus.InputContext:
<interface name="org.freedesktop.IBus.InputContext"> <method name="ProcessKeyEvent"> <arg type="u" name="keyval" direction="in"/> <arg type="u" name="keycode" direction="in"/> <arg type="u" name="state" direction="in"/> <arg type="b" name="handled" direction="out"/> </method> <method name="SetCursorLocation"> <arg type="i" name="x" direction="in"/> <arg type="i" name="y" direction="in"/> <arg type="i" name="w" direction="in"/> <arg type="i" name="h" direction="in"/> </method> <method name="SetCursorLocationRelative"> <arg type="i" name="x" direction="in"/> <arg type="i" name="y" direction="in"/> <arg type="i" name="w" direction="in"/> <arg type="i" name="h" direction="in"/> </method> <method name="ProcessHandWritingEvent"> <arg type="ad" name="coordinates" direction="in"/> </method> <method name="CancelHandWriting"> <arg type="u" name="n_strokes" direction="in"/> </method> <method name="FocusIn"/> <method name="FocusOut"/> <method name="Reset"/> <method name="SetCapabilities"> <arg type="u" name="caps" direction="in"/> </method> <method name="PropertyActivate"> <arg type="s" name="name" direction="in"/> <arg type="u" name="state" direction="in"/> </method> <method name="SetEngine"> <arg type="s" name="name" direction="in"/> </method> <method name="GetEngine"> <arg type="v" name="desc" direction="out"/> </method> <method name="SetSurroundingText"> <arg type="v" name="text" direction="in"/> <arg type="u" name="cursor_pos" direction="in"/> <arg type="u" name="anchor_pos" direction="in"/> </method> <signal name="CommitText"> <arg type="v" name="text"/> </signal> <signal name="ForwardKeyEvent"> <arg type="u" name="keyval"/> <arg type="u" name="keycode"/> <arg type="u" name="state"/> </signal> <signal name="UpdatePreeditText"> <arg type="v" name="text"/> <arg type="u" name="cursor_pos"/> <arg type="b" name="visible"/> </signal> <signal name="ShowPreeditText"/> <signal name="HidePreeditText"/> <signal name="UpdateAuxiliaryText"> <arg type="v" name="text"/> <arg type="b" name="visible"/> </signal> <signal name="ShowAuxiliaryText"/> <signal name="HideAuxiliaryText"/> <signal name="UpdateLookupTable"> <arg type="v" name="table"/> <arg type="b" name="visible"/> </signal> <signal name="ShowLookupTable"/> <signal name="HideLookupTable"/> <signal name="PageUpLookupTable"/> <signal name="PageDownLookupTable"/> <signal name="CursorUpLookupTable"/> <signal name="CursorDownLookupTable"/> <signal name="RegisterProperties"> <arg type="v" name="props"/> </signal> <signal name="UpdateProperty"> <arg type="v" name="prop"/> </signal> <property type="(uu)" name="ContentType" access="write"/> </interface>
- Client 呼叫 IBus daemon 的 SetGlobalEngine (全域輸入法)或 input context 的 SetEngine (非全域輸入法)來切換輸入法,此時 IBus daemon 使用 factory 來產生 engine。Factory 的 bus name 由自己決定,例如酷音位在 org.freedesktop.IBus.Chewing,factory 透過設定檔或是 RegisterComponent 來告訴 IBus daemon 它的 bus name。Factory 產生 engine 時回傳該 engine 的 object path,bus name 則跟 factory 本身相同。Factory 主要的 interface 是 org.freedesktop.IBus.Factory:
<interface name="org.freedesktop.IBus.Factory"> <method name="CreateEngine"> <arg type="s" name="name" direction="in"/> <arg type="o" name="arg_1" direction="out"/> </method> </interface>
- Engine 是真正作輸出入處理的元件,主要 interface 是 org.freedeskstop.IBus.Engine:
<interface name="org.freedesktop.IBus.Engine"> <method name="ProcessKeyEvent"> <arg type="u" name="keyval" direction="in"/> <arg type="u" name="keycode" direction="in"/> <arg type="u" name="state" direction="in"/> <arg type="b" name="arg_3" direction="out"/> </method> <method name="SetCursorLocation"> <arg type="i" name="x" direction="in"/> <arg type="i" name="y" direction="in"/> <arg type="i" name="w" direction="in"/> <arg type="i" name="h" direction="in"/> </method> <method name="ProcessHandWritingEvent"> <arg type="ad" name="coordinates" direction="in"/> </method> <method name="CancelHandWriting"> <arg type="u" name="n_strokes" direction="in"/> </method> <method name="SetCapabilities"> <arg type="u" name="caps" direction="in"/> </method> <method name="PropertyActivate"> <arg type="s" name="name" direction="in"/> <arg type="u" name="state" direction="in"/> </method> <method name="PropertyShow"> <arg type="s" name="name" direction="in"/> </method> <method name="PropertyHide"> <arg type="s" name="name" direction="in"/> </method> <method name="CandidateClicked"> <arg type="u" name="index" direction="in"/> <arg type="u" name="button" direction="in"/> <arg type="u" name="state" direction="in"/> </method> <method name="FocusIn"/> <method name="FocusOut"/> <method name="Reset"/> <method name="Enable"/> <method name="Disable"/> <method name="PageUp"/> <method name="PageDown"/> <method name="CursorUp"/> <method name="CursorDown"/> <method name="SetSurroundingText"> <arg type="v" name="text" direction="in"/> <arg type="u" name="cursor_pos" direction="in"/> <arg type="u" name="anchor_pos" direction="in"/> </method> <signal name="CommitText"> <arg type="v" name="text"/> </signal> <signal name="UpdatePreeditText"> <arg type="v" name="text"/> <arg type="u" name="cursor_pos"/> <arg type="b" name="visible"/> <arg type="u" name="mode"/> </signal> <signal name="UpdateAuxiliaryText"> <arg type="v" name="text"/> <arg type="b" name="visible"/> </signal> <signal name="UpdateLookupTable"> <arg type="v" name="table"/> <arg type="b" name="visible"/> </signal> <signal name="RegisterProperties"> <arg type="v" name="props"/> </signal> <signal name="UpdateProperty"> <arg type="v" name="prop"/> </signal> <signal name="ForwardKeyEvent"> <arg type="u" name="keyval"/> <arg type="u" name="keycode"/> <arg type="u" name="state"/> </signal> <property type="(uu)" name="ContentType" access="write"/> </interface>
- Panel 位在 bus name: org.freedesktop.IBus.Panel,object path: /org/freedesktop/IBus/Panel,主要 interace 是 org.freedesktop.IBus.Panel:
<interface name="org.freedesktop.IBus.Panel"> <method name="UpdatePreeditText"> <arg type="v" name="text" direction="in"/> <arg type="u" name="cursor_pos" direction="in"/> <arg type="b" name="visible" direction="in"/> </method> <method name="ShowPreeditText"/> <method name="HidePreeditText"/> <method name="UpdateAuxiliaryText"> <arg type="v" name="text" direction="in"/> <arg type="b" name="visible" direction="in"/> </method> <method name="ShowAuxiliaryText"/> <method name="HideAuxiliaryText"/> <method name="UpdateLookupTable"> <arg type="v" name="table" direction="in"/> <arg type="b" name="visible" direction="in"/> </method> <method name="ShowLookupTable"/> <method name="HideLookupTable"/> <method name="CursorUpLookupTable"/> <method name="CursorDownLookupTable"/> <method name="PageUpLookupTable"/> <method name="PageDownLookupTable"/> <method name="RegisterProperties"> <arg type="v" name="props" direction="in"/> </method> <method name="UpdateProperty"> <arg type="v" name="prop" direction="in"/> </method> <method name="FocusIn"> <arg type="o" name="ic" direction="in"/> </method> <method name="FocusOut"> <arg type="o" name="ic" direction="in"/> </method> <method name="DestroyContext"> <arg type="o" name="ic" direction="in"/> </method> <method name="SetCursorLocation"> <arg type="i" name="x" direction="in"/> <arg type="i" name="y" direction="in"/> <arg type="i" name="w" direction="in"/> <arg type="i" name="h" direction="in"/> </method> <method name="SetCursorLocationRelative"> <arg type="i" name="x" direction="in"/> <arg type="i" name="y" direction="in"/> <arg type="i" name="w" direction="in"/> <arg type="i" name="h" direction="in"/> </method> <method name="Reset"/> <method name="StartSetup"/> <method name="StateChanged"/> <method name="HideLanguageBar"/> <method name="ShowLanguageBar"/> <method name="ContentType"> <arg type="u" name="purpose" direction="in"/> <arg type="u" name="hints" direction="in"/> </method> <signal name="CursorUp"/> <signal name="CursorDown"/> <signal name="PageUp"/> <signal name="PageDown"/> <signal name="PropertyActivate"> <arg type="s" name="prop_name"/> <arg type="i" name="prop_state"/> </signal> <signal name="PropertyShow"> <arg type="s" name="prop_name"/> </signal> <signal name="PropertyHide"> <arg type="s" name="prop_name"/> </signal> <signal name="CandidateClicked"> <arg type="u" name="index"/> <arg type="u" name="button"/> <arg type="u" name="state"/> </signal> </interface>
- IBus Config 位在 bus name: org.freedesktop.IBus.Config,object path: /org/freedesktop/IBus/Config,主要的 interface 是 org.freedesktop.IBus.Config:
<interface name="org.freedesktop.IBus.Config"> <method name="SetValue"> <arg type="s" name="section" direction="in"/> <arg type="s" name="name" direction="in"/> <arg type="v" name="value" direction="in"/> </method> <method name="GetValue"> <arg type="s" name="section" direction="in"/> <arg type="s" name="name" direction="in"/> <arg type="v" name="value" direction="out"/> </method> <method name="GetValues"> <arg type="s" name="section" direction="in"/> <arg type="a{sv}" name="values" direction="out"/> </method> <method name="UnsetValue"> <arg type="s" name="section" direction="in"/> <arg type="s" name="name" direction="in"/> </method> <signal name="ValueChanged"> <arg type="s" name="section"/> <arg type="s" name="name"/> <arg type="v" name="value"/> </signal> </interface>
- org.freedesktop.IBus.Notifications: only for GTK2?
Tags
None
Subscribers
None
- Last Author
- iongchun
- Last Edited
- May 17 2017, 1:18 PM