如何在切换键盘布局时启动命令的自动执行?

如何在切换键盘布局时启动命令的自动执行?

我想要执行以下命令:

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命令并修改快捷方式,这样每次单击快捷方式时,程序都会运行。还有另一种方法,即通过现有的GioAPI。当您为 Ubuntu 或其他使用 GNOME 相关桌面的系统开发适当的桌面应用程序时,将使用此类 API。下面的脚本说明了使用GioAPI 的方法。

#!/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)

设置

  1. 将脚本复制到一个空文件中,另存为change_lang.py
  2. 通过以下命令测试运行脚本:

    python3 /path/to/change_lang.py +
    

    以及可选的:

    python3 /path/to/change_lang.py -
    

    您的布局应该改变并且您的命令应该运行。

  3. 如果一切正常,请打开系统设置,转到“键盘”>“快捷方式”>“输入”。单击快捷方式以切换源(在右侧,设置快捷方式),然后按退格键以禁用快捷方式。

    在此处输入图片描述

  4. 现在将相同的快捷键添加到自定义快捷键中:选择:系统设置>“键盘”>“快捷键”>“自定义快捷键”。单击“+”并添加命令:

    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 或调用时运行选项之间进行选择则取决于个人喜好。

还请注意,脚本首先更改语言,然后运行其他命令。 两个答案的响应没有明显差异。

相关内容