我想要执行以下命令:
xmodmap -e "keycode 52=y"
xmodmap -e "keycode 29=z"
每当我切换键盘布局 ( Shift+ Alt) 时。有什么办法吗?
答案1
Ubuntu 上如何实现语言切换
默认情况下,Ubuntu 的输入源设置在名为的数据库中gsettings
。每个设置都有一个与之关联的特定架构。特别是,语言切换与架构相关org.gnome.desktop.input-sources
。这是我们对所有现代 Ubuntu 版本感兴趣的。
更具体地说,我们感兴趣的是它的键current
。当您通过 GUI 更改语言时,该键会被修改。您可以用它做很多事情,从 在命令行中切换输入语言到为每种输入法定义快捷方式, 甚至为每个单独的应用程序设置输入法可以做到。一种方法是通过gsettings
命令或dconf
命令。这些是位于/usr/bin/
文件夹中的外部程序(这与 Jacob 的答案使用的方法相同)。另一种方法是通过 Python 编程语言的特定实用程序集(实际上是 API)。这是我将在我的答案中展示的方法。
需要注意的是,这gsettings
并不总是有效。如果您使用的是非标准输入法,例如fcitx
,这可能不是真的。事实上搜狗拼音(中文输入法)使用另一种称为 的方法dbus
,因此使用 的方法gsettings
不起作用。但对于使用默认 Ubuntu 的简单情况,gsettings
数据库就足够了。
检测输入法变化
Jacob 的做法是单次运行外部gsettings
命令并修改快捷方式,这样每次单击快捷方式时,程序都会运行。还有另一种方法,即通过现有的Gio
API。当您为 Ubuntu 或其他使用 GNOME 相关桌面的系统开发适当的桌面应用程序时,将使用此类 API。下面的脚本说明了使用Gio
API 的方法。
#!/usr/bin/env python
from __future__ import print_function
from gi.repository import Gio, GObject
import subprocess
def on_changed(settings, key):
# This will run if specific key of a schema changed
print("Language changed")
# Do something else here, for example call external program
subprocess.call(['xmodmap','-e', 'keycode 52=y'])
subprocess.call(['xmodmap','-e', 'keycode 29=z'])
def main():
# We're focusing on this specific schema
settings = Gio.Settings("org.gnome.desktop.input-sources")
# Once the "current" key changes, on-changed function will run
settings.connect("changed::current", on_changed)
loop = GObject.MainLoop()
loop.run()
if __name__ == "__main__":
main()
与干扰快捷方式相比,这种方法有明显的优势:
- 您不必编辑快捷方式。我不会夸大这一点,但这个答案的设置只是制作脚本登录时自动启动。
- 因为它使用 GIO 事件 API,所以我们每次更改语言时都不会两次按下 gsettings。我们让语言更改像往常一样进行。这使得更改语言时速度更快,资源占用更少。
- 因为它总是在监听,所以我们永远不需要等待 Python 开始加载脚本。它只会在登录时加载一次,然后就可以进行更改了。
- 因为它使用了 API,任何事物否则,改变输入语言(菜单图标、gsettings)将触发该事件,从而触发该脚本。
另一位发帖者的评论中有一些担忧,但尽管这是一个持久脚本,但也有其优点。它消耗的微薄资源远远超过了它只会消耗一小部分 RAM 的事实。
答案2
正在执行的文件?
我担心切换源是 Unity 的内置功能,不能作为外部的 CLI 选项使用。然而但这并不意味着我们没有选择来实现您的确切目标。
脚本解决方案将更改布局与您的命令结合起来
替换原始快捷方式
可以通过以下命令获取输入源:
gsettings get org.gnome.desktop.input-sources sources
输出如下:
[('xkb', 'us+intl'), ('xkb', 'us'), ('xkb', 'nl'), ('xkb', 'be')]
可以使用以下命令设置布局:
gsettings set org.gnome.desktop.input-sources current <index>
这样,我们就可以用脚本版本切换到下一种语言和同时运行您的命令。
剧本
#!/usr/bin/env python3
import subprocess
import ast
import sys
arg = sys.argv[1]
key = "org.gnome.desktop.input-sources"
def get(cmd): return subprocess.check_output(cmd).decode("utf-8")
def run(cmd): subprocess.call(["/bin/bash", "-c", cmd])
langs = len(ast.literal_eval(get(["gsettings", "get", key, "sources"])))
currlang = int(get(["gsettings", "get", key, "current"]).split()[-1].strip())
if arg == "+":
next_lang = currlang+1 if currlang < langs-1 else 0
elif arg == "-":
next_lang = currlang-1 if currlang > 0 else langs-1
for cmd in [
"gsettings set "+key+" current "+str(next_lang),
'xmodmap -e "keycode 52=y"',
'xmodmap -e "keycode 29=z"',
]: run(cmd)
设置
- 将脚本复制到一个空文件中,另存为
change_lang.py
通过以下命令测试运行脚本:
python3 /path/to/change_lang.py +
以及可选的:
python3 /path/to/change_lang.py -
您的布局应该改变并且您的命令应该运行。
如果一切正常,请打开系统设置,转到“键盘”>“快捷方式”>“输入”。单击快捷方式以切换源(在右侧,设置快捷方式),然后按退格键以禁用快捷方式。
现在将相同的快捷键添加到自定义快捷键中:选择:系统设置>“键盘”>“快捷键”>“自定义快捷键”。单击“+”并添加命令:
python3 /path/to/change_lang.py +
到您刚刚在步骤2中禁用的快捷方式。
此外你能设置快捷方式以相反方向移动(从列表中设置上一个源):
python3 /path/to/change_lang.py -
就是这样。现在更改语言与您想要运行的命令结合在一起了。
它能做什么
无论何时按下快捷方式,都会通过以下命令调用脚本并查看当前语言:
gsettings get org.gnome.desktop.input-sources current
脚本随后根据参数通过以下命令移动到下一个或上一个:
gsettings set org.gnome.desktop.input-sources current <index>
资源
使用gsettings
非常低效,并且通过将设置语言的命令与命令结合起来,脚本仅在更改语言时运行。
我相信这是最优雅的方式,虽然你不会注意到你的电费,但从长远来看,这是资源消耗最少的方式。然而,在持续运行的进程、使用 API 或调用时运行选项之间进行选择则取决于个人喜好。
还请注意,脚本首先更改语言,然后运行其他命令。 两个答案的响应没有明显差异。