Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

只要複製 profile 這樣就不需要用fcitx-imlist 去指定輸入法了嗎? #1

Open
changchichung opened this issue Oct 15, 2018 · 11 comments

Comments

@changchichung
Copy link

你好,我一直在研究怎麼用命令列模式去設定user端的輸入法(fcitx-chewing)
所以只要在每個使用者的家目錄底下新增事先編輯好的 .config/fcitx/profile
每個使用者登入之後就可以使用fcitx的輸入法了嗎?

@samwhelp
Copy link
Owner

samwhelp commented Oct 15, 2018

執行

$ im-config -n fcitx

重開機或是重新登入,「輸入法框架」就會採用「fcitx」。

之前相關的討論可以參考

也可以執行下面指令,觀看相關的說明

  • $ man im-config
  • $ view /usr/share/doc/im-config/README.Debian.gz

可以對照專案裡面的寫法

================================================================================

執行「im-config -n fcitx」,這個「設定值」會存在「~/.xinputrc」這個檔案。

執行下面指令觀看「~/.xinputrc」這個檔案的內容。

$ cat ~/.xinputrc

顯示

# im-config(8) generated on Mon, 15 Oct 2018 20:33:39 +0800
run_im fcitx
# im-config signature: 929d557369ad4551e92933bda57a601f  -

主要是「run_im fcitx」那一行。

可以對照專案裡面的寫法

================================================================================

我目前測試的環境「Ubutnu 18.04」。

若是要讓「fcitx-chewing」,在「候選輸入法列表」裡,
可以透過「圖形界面程式」編輯 (「fcitx-configtool」或是「fcitx-config-gtk3」),

我目前還沒找到「指令」編輯的方法,所以我就直接編輯「~/.config/fcitx/profile」。

也就是我專案裡面採用的方式

我目前找過的指令如下

相關的說明可以執行

目前還沒找到指令編輯的方法。

================================================================================

另外也找過「DBus」的方式,

執行

$ qdbus | grep fcitx

顯示

org.fcitx.Fcitx

執行

$ qdbus org.fcitx.Fcitx

顯示

/
/MenuBar
/StatusNotifierItem
/inputmethod
/keyboard
/kimpanel

執行

$ qdbus org.fcitx.Fcitx /inputmethod

顯示

method QString org.freedesktop.DBus.Introspectable.Introspect()
method QDBusVariant org.freedesktop.DBus.Properties.Get(QString interface_name, QString property_name)
method QVariantMap org.freedesktop.DBus.Properties.GetAll(QString interface_name)
signal void org.freedesktop.DBus.Properties.PropertiesChanged(QString interface_name, QVariantMap changed_properties, QStringList invalidated_properties)
method void org.freedesktop.DBus.Properties.Set(QString interface_name, QString property_name, QDBusVariant value)
property readwrite QString org.fcitx.Fcitx.InputMethod.CurrentIM
property readwrite QDBusRawType::a(sssb) org.fcitx.Fcitx.InputMethod.IMList
method void org.fcitx.Fcitx.InputMethod.ActivateIM()
method void org.fcitx.Fcitx.InputMethod.Configure()
method void org.fcitx.Fcitx.InputMethod.ConfigureAddon(QString addon)
method void org.fcitx.Fcitx.InputMethod.ConfigureIM(QString im)
method int org.fcitx.Fcitx.InputMethod.CreateIC(uint& keyval1, uint& state1, uint& keyval2, uint& state2)
method int org.fcitx.Fcitx.InputMethod.CreateICv2(QString appname, bool& enable, uint& keyval1, uint& state1, uint& keyval2, uint& state2)
method int org.fcitx.Fcitx.InputMethod.CreateICv3(QString appname, int pid, bool& enable, uint& keyval1, uint& state1, uint& keyval2, uint& state2)
method void org.fcitx.Fcitx.InputMethod.Exit()
method QString org.fcitx.Fcitx.InputMethod.GetCurrentIM()
method int org.fcitx.Fcitx.InputMethod.GetCurrentState()
method QString org.fcitx.Fcitx.InputMethod.GetCurrentUI()
method QString org.fcitx.Fcitx.InputMethod.GetIMAddon(QString im)
method void org.fcitx.Fcitx.InputMethod.InactivateIM()
method void org.fcitx.Fcitx.InputMethod.ReloadAddonConfig(QString addon)
method void org.fcitx.Fcitx.InputMethod.ReloadConfig()
method void org.fcitx.Fcitx.InputMethod.ResetIMList()
method void org.fcitx.Fcitx.InputMethod.Restart()
method void org.fcitx.Fcitx.InputMethod.SetCurrentIM(QString im)
method void org.fcitx.Fcitx.InputMethod.ToggleIM()

下列出上面四行要討論的

property readwrite QString org.fcitx.Fcitx.InputMethod.CurrentIM
method QString org.fcitx.Fcitx.InputMethod.GetCurrentIM()
method void org.fcitx.Fcitx.InputMethod.SetCurrentIM(QString im)
method void org.fcitx.Fcitx.InputMethod.ToggleIM()

執行

$ qdbus org.fcitx.Fcitx /inputmethod org.fcitx.Fcitx.InputMethod.CurrentIM

顯示

fcitx-keyboard-us

執行

$ qdbus org.fcitx.Fcitx /inputmethod org.fcitx.Fcitx.InputMethod.CurrentIM chewing

這時候輸入法,就會切換成「fcitx-chewing」。

接著再執行

$ qdbus org.fcitx.Fcitx /inputmethod org.fcitx.Fcitx.InputMethod.CurrentIM fcitx-keyboard-us

就會切回原來的英文輸入。

上面是透過「property」的讀寫,上面也有提供「method」

method QString org.fcitx.Fcitx.InputMethod.GetCurrentIM()
method void org.fcitx.Fcitx.InputMethod.SetCurrentIM(QString im)

也就是寫的部份,可以執行

$ qdbus org.fcitx.Fcitx /inputmethod org.fcitx.Fcitx.InputMethod.SetCurrentIM chewing
$ qdbus org.fcitx.Fcitx /inputmethod org.fcitx.Fcitx.InputMethod.SetCurrentIM fcitx-keyboard-us

也就是讀的部份,可以執行

$ qdbus org.fcitx.Fcitx /inputmethod org.fcitx.Fcitx.InputMethod.GetCurrentIM

另外還有提供一個「method」

method void org.fcitx.Fcitx.InputMethod.ToggleIM()

也就是可以多次執行下面指令,來做輸入法的切換。

$ qdbus org.fcitx.Fcitx /inputmethod org.fcitx.Fcitx.InputMethod.ToggleIM

這個動作也可以透過「fcitx-remote」這個指令來執行。

$ fcitx-remote -t
$ fcitx-remote -t

指令輸入法切換,則是執行下面指令

$ fcitx-remote -s chewing
$ fcitx-remote -s fcitx-keyboard-us

另外執行「qdbus org.fcitx.Fcitx /inputmethod」,還有看到一個可以讀寫的「property」,

property readwrite QDBusRawType::a(sssb) org.fcitx.Fcitx.InputMethod.IMList

這個跟「IMList」應該有關,也就是「候選輸入法列表」。

目前只有會讀的部份,可以執行下面指令

$ qdbus --literal org.fcitx.Fcitx /inputmethod org.fcitx.Fcitx.InputMethod.IMList

可以對照「~/.config/fcitx/profile」裡的「EnabledIMList=」那一行。

寫的部份,尚未去研究指令怎麼下, Orz...

================================================================================

若真的要採用指令的方式,來維護「候選輸入法列表」,
可能要研究「fcitx-configtool」那一段程式碼是怎麼撰寫的,
然後改寫成指令,不過目前還沒去深究這一段,只是初步猜想。

================================================================================

以上提供參考

報告完畢

:-)

@changchichung
Copy link
Author

哇,感謝你論文級的回覆!

我是因為我們公司的client都是用ubuntu ,最近在研擬要升級到18.04
所以才研究這個輸入法的問題
用imconfig 來設定輸入法框架這個部份我了解
但就是一直沒辦法順利設定輸入法(注音、倉頡)
我是沒想到可以用qdbus 來做..
一直卡在用 dconf watch 看了半天,怎麼改設定也沒看到相關的數值

也曾經測試過把修改好的profile放到各個user的對應目錄去
可是user登入後,還是沒有啟動注音

上面這個是我主要的疑問,因為看起來好像就是在這裡改就好了..

我最後是用 fcitx-imconfig這個工具,在每個使用者家目錄的 .config/autostart 做一個 fcitx.desktop的檔案
然後去執行一個小script 裡面跑 fcitx-imconfig 來啟用注音、倉頡
不過一開始也還是不行,雖然程式有跑,但是輸入法就是沒有出現
後來想到是不是因為在執行的時候,gdm還沒有完全啟動,所以fcitx-imconfig執行有問題
放了個 sleep 30 進去,果然就可以順利啟動輸入法

只是在想應該還有更直觀的方式去處理..

@samwhelp
Copy link
Owner

我猜測,您創造各個使用者的「$HOME/.config/fcitx/profile」,
可能是使用「sudo」或是「root帳號」來做這件事,
所以一開始「$HOME/.config/fcitx/profile 」的擁有者和群組應該是「root.root」,
我剛測試,當「fcitx」啟動的時候,這樣的情況下,好像就把舊去除,
然後產生新的「$HOME/.config/fcitx/profile」,並且該檔案的擁有者和群組就變成該使用者,
不過「EnabledIMList=」那一行,就不是您原先設定的了,
所以也就沒有「fcitx-keyboard-us:True,chewing:True」,
而是「fcitx-keyboard-us:True,chewing:False」。
所以我猜測,才會發生您說的狀況。

也曾經測試過把修改好的profile放到各個user的對應目錄去
可是user登入後,還是沒有啟動注音

================================================================================

正常的狀況下

執行

$ ls -al ~/.config/fcitx/profile

顯示

-rw------- 1 user user 20608 Oct 16 12:34 /home/user/.config/fcitx/profile

註:上面的「user」,根據您的帳號而定。

================================================================================

以上參考,您可以再測試確認看看。

================================================================================

關於

一直卡在用 dconf watch 看了半天,怎麼改設定也沒看到相關的數值

fcitx 應該是沒有使用到「gsettings」的機制,
通常若有的話,可以到「/usr/share/glib-2.0/schemas/」找到相關的「gschema」

我在我的系統執行

$ ls /usr/share/glib-2.0/schemas/ | grep fcitx -i

並沒有顯示相關的

舉例,若是「gedit」

執行

$ ls /usr/share/glib-2.0/schemas/ | grep gedit -i

顯示

org.gnome.gedit.enums.xml
org.gnome.gedit.gschema.xml
org.gnome.gedit.plugins.externaltools.gschema.xml
org.gnome.gedit.plugins.filebrowser.enums.xml
org.gnome.gedit.plugins.filebrowser.gschema.xml
org.gnome.gedit.plugins.pythonconsole.gschema.xml
org.gnome.gedit.plugins.time.enums.xml
org.gnome.gedit.plugins.time.gschema.xml

執行

$ dpkg -L gedit-common | grep gschema

顯示

/usr/share/glib-2.0/schemas/org.gnome.gedit.gschema.xml
/usr/share/glib-2.0/schemas/org.gnome.gedit.plugins.externaltools.gschema.xml
/usr/share/glib-2.0/schemas/org.gnome.gedit.plugins.filebrowser.gschema.xml
/usr/share/glib-2.0/schemas/org.gnome.gedit.plugins.pythonconsole.gschema.xml
/usr/share/glib-2.0/schemas/org.gnome.gedit.plugins.time.gschema.xml

================================================================================

關於

我是沒想到可以用qdbus 來做..

因為「fcitx」有提供「dbus」的介面,所以可以透過「qdbus」來溝通,
另外也有其他的指令可以使用,例如「gdbus」或是「dbus-send」。

或是也可以「透過寫程式」使用「DBus」的機制來溝通。

例如

================================================================================

關於「gsettings」,「dconf」,「qdbus」,「gdbus」,「dbus-send」,這幾個議題,
可以參考「[索引] 泛Ubuntu 安裝調校
這裡面有紀錄以前的一些討論案例

================================================================================

額外一提

另外「fcitx」也有提供「GObject Introspection」的機制,所以也可以透過這個機制溝通。

可以參考

相關的套件是「gir1.2-fcitx-1.0」。

================================================================================

:-)

@changchichung
Copy link
Author

沒有耶,我用ansible跑,有設定相關權限

root@hqpc056:~# ls -lart /home/dengm/.config/fcitx/
total 92
drwx------  2 dengm dengm  4096  十   9 13:50 log
-rw-rw-r--  1 dengm dengm  3209  十   9 13:50 config
drwx------  2 dengm dengm  4096  十   9 13:50 dbus
drwx------  2 dengm dengm  4096  十   9 13:50 clipboard
drwx------  2 dengm dengm  4096  十   9 13:50 data
drwx------  2 dengm dengm  4096  十   9 14:04 chewing
drwxr-xr-x 15 dengm dengm  4096  十   9 15:30 ..
drwx------  2 dengm dengm  4096  十  15 10:51 conf
-rw-------  1 dengm dengm 28742  十  15 10:54 cached_layout
-rw-------  1 dengm dengm 20579  十  15 15:12 profile
drwx------  8 dengm dengm  4096  十  15 15:12 .
root@hqpc056:~# 

@samwhelp
Copy link
Owner

另外我想到還有一種情形,
就是「fcitx」已經執行了,然後這時候若直接修改「$HOME/.config/fcitx/profile」,
當重新啟動「fcitx」,我觀察到「fcitx」應該是會回寫「$HOME/.config/fcitx/profile」,
所以原本修改的內容,應該就會被蓋掉。

所以要直接修改「$HOME/.config/fcitx/profile」,應該要在「fcitx」沒有在執行的時候做這個動作。

另外根據
https://lazka.github.io/pgi-docs/index.html#Fcitx-1.0/classes/InputMethod.html#Fcitx.InputMethod.set_imlist

我寫了一個範例fcitx-imlist.py

只要執行

$ ./fcitx-imlist.py -e chewing

就可以將「fcitx-chewing」加入「輸入法候選列表」。

更多詳細的用法,請參考「README.md」。

其他的方式,還在研究中,若有心得,我會再貼上來

:-)

@changchichung
Copy link
Author

就是「fcitx」已經執行了,然後這時候若直接修改「$HOME/.config/fcitx/profile」,
當重新啟動「fcitx」,我觀察到「fcitx」應該是會回寫「$HOME/.config/fcitx/profile」,
所以原本修改的內容,應該就會被蓋掉。

有可能唷,我今天來測試看看..

太感謝你的程式了!

@changchichung
Copy link
Author

果然 直接改profile ,下次啟動fcitx 就會被蓋掉
不過,似乎也不是蓋掉,有修改的值還是會保留,只是會附加一堆有的沒的輸入法到enableimlist
難怪怎麼改profile都沒用..

是說,我也找不到它從哪裡讀取enableimlist的內容然後附加到profile裡面去
如果找得到這個來源,那直接改這邊,應該就可以幫每個user做好預設的輸入法了..
繼續研究看看!

@samwhelp
Copy link
Owner

samwhelp commented Oct 19, 2018

看起來應該還不需要改到原本的程式,只需要善用它原本提供的機制就可以了。

一樣可以直接修改「$HOME/.config/fcitx/profile」,
只是修改前,先停掉「fcitx」,
修改後,再啟動「fcitx」。
在寫「script」的時候,可以透過「fcitx-remote」這個指令來判斷「fcitx是否執行中」。
若「fcitx」正在執行中,則執行「fcitx-remote」回傳的「Exit Status」會是「0」,
若「fcitx」尚未執行,則執行「fcitx-remote」回傳的「Exit Status」會是「1」,
在寫「Shell Script」時,「Exit Status」可以透過「$?」得到,
例如:

fcitx-remote
echo $?

關於「Exit Status」之前有寫過一篇「簡易教學」可以參考。

另外我有寫一個「完整範例 - install-fcitx-chewing」,也可以對照著參考。

關於「fcitx-remote」的用法,也可以參考「/usr/bin/fcitx-autostart」這個「Shell Script」。

================================================================================

如何透過指令設定「IMList」的方式我研究出來了,

目前研究出來的是透過「gdbus」這個指令,這個指令是來自於「libglib2.0-bin」這個套件

執行範例如下

$ gdbus call --session --dest org.fcitx.Fcitx --object-path /inputmethod --method org.freedesktop.DBus.Properties.Set org.fcitx.Fcitx.InputMethod IMList '<[("Keyboard - English (US)", "fcitx-keyboard-us", "en", true), ("Chewing", "chewing", "zh_TW", true)]>'

所以剛剛的「install-fcitx-chewing」,
我也改寫了另一個「完整範例 - install-fcitx-chewing-gdbus」,
可以對照著看。

python版,則是可以參考這個「範例」,
或是「fcitx-imlist.py」另一個「實作範例」。

================================================================================

另外之前有寫一個程式「pygi-fcitx/fcitx-imlist.py」,

那個程式是透過「pygi-fcitx」的機制去實作的。

後來我改寫了一個「pygi-dbus/fcitx-imlist.py」,

是透過「pygi-gio-dbus」的的機制去實作的。

我也補充了一些「範例」,是關於「qdbus」,「gdbus」,「dbus-send」這幾個指令的下法,

供您對照參考。

================================================================================

另外關於「fcitx」的程式碼,我列幾個連結,給您參考

可以發現到「Fctix」在實作「GObject Introspection」的機制時,
在呼叫一些功能時,也是透過「D-Bus」去呼叫那些功能。

================================================================================

以上提供參考

報告完畢

:-)

@changchichung
Copy link
Author

哇賽,你寫程式跟喝水一樣簡單耶 XD

我比較粗殘,現在的作法是取消 fcitx-autostart,改用user登入時去執行一支小script,裡面就砍掉fcitx / copy fcitx-profile / 啟動 fcitx

至於

$ gdbus call --session --dest org.fcitx.Fcitx --object-path /inputmethod --method org.freedesktop.DBus.Properties.Set org.fcitx.Fcitx.InputMethod IMList '<[("Keyboard - English (US)", "fcitx-keyboard-us", "en", true), ("Chewing", "chewing", "zh_TW", true)]>'

這一段的指令我測試是沒有作用的,他還是會去讀取fcitx profile ...而且剛剛設定好的profile又會被蓋掉,可能是fcitx 預設就是會從某個地方去產生這個profile,然後複製過來

所以我在想還是要能找到 fcitx profile 的來源,看能不能直接修改source ,不然在profile裡面哪個enableimlist 一大串,看了也實在很討厭..

@samwhelp
Copy link
Owner

補充一點,只要在fcitx尚未執行的情況下,修改「$HOME/.config/fcitx/profile」,

將「EnabledIMList」那一行修改如下

EnabledIMList=fcitx-keyboard-us:True

完整的「profile」可以參考「這裡」,

上面的修改完後,當「fcitx」啟動後,就會自動附加「chewing:True」和「cangjie5:True」

EnabledIMList=fcitx-keyboard-us:True,chewing:True,cangjie5:True

後面還有一長串附加的,我就不貼了。

注意:修改「profile」這個方式其實只要修改一次就行了,不需要每次登入都做這個動作。

因為剛剛有看到一篇「文章」,猜測是您寫的紀錄。

提供另一個參考文章

https://blog.gtwang.org/linux/linux-useradd-command-tutorial-examples/

供您參考,也許您有新的靈感,如何創造新的使用者。

================================================================================

至於您說的下面指令沒有作用,
我猜測您再執行下面的指令的時候,「fcitx」應該是在還沒有執行的狀態下,所以才沒有作用。

$ gdbus call --session --dest org.fcitx.Fcitx --object-path /inputmethod --method org.freedesktop.DBus.Properties.Set org.fcitx.Fcitx.InputMethod IMList '<[("Keyboard - English (US)", "fcitx-keyboard-us", "en", true), ("Chewing", "chewing", "zh_TW", true)]>'

================================================================================

額外一提,前兩天我才曉得您提到的「fcitx-imlist」,

執行

$ apt-cache show fcitx-imlist | grep '^Homepage'

顯示

Homepage: https://github.com/kenhys/fcitx-imlist

從上面就可以找到「GitHub / fcitx-imlist」上的網址,可以找到相關原始碼

或是也可以執行下面指令,下載「Source Package: fcitx-imlist」下來看

$ apt-get source fcitx-imlist

要執行上面指令的前置作業,可以參考「#24 回覆: Ubuntu 17.10 推出

或是我的「Ubuntu 18.04 Apt Source List」設定。

也可以執行下面指令,下載「Source Package: fcitx」下來看

$ apt-get source fcitx

可以對照上面我之前的「回覆」下面有列一些參考連結

一些套件操作的討論案例和參考連結,以前有做一個紀錄放在「[索引] 套件操作實務

================================================================================

以上補充

:-)

@samwhelp
Copy link
Owner

samwhelp commented Apr 8, 2023

一直要補充,一直忘了,剛又逛到這個頁面,就來補充下面的概念

有一種方式,就是在「/etc/skel」,放置您的設定檔,

當您創建新帳號的時候,有機制會將「/etc/skel」的檔案,複製到「該使用者」的「家目錄」。

這應該可以符合您原本想要的需求。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants