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

hue*_*hue 6 command-line keyboard automation layout

我想执行以下命令:

xmodmap -e "keycode 52=y"
xmodmap -e "keycode 29=z"
Run Code Online (Sandbox Code Playgroud)

每当我切换键盘布局 ( Shift+ Alt) 时。有没有办法做到这一点?

Ser*_*nyy 10

如何在 Ubuntu 上实现语言切换

默认情况下,Ubuntu 的输入源设置在名为gsettings. 每个设置都有一个与之关联的特定架构。特别是,语言切换与org.gnome.desktop.input-sources模式相关联。这是我们对所有现代 Ubuntu 版本都感兴趣的。

更具体地说,我们对它的 key 感兴趣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()
Run Code Online (Sandbox Code Playgroud)

与干扰快捷方式相比​​,这种方法有明显的优势:

  • 您不必编辑快捷方式。我不会夸大这一点,但此答案的设置只是使脚本在您登录时自动启动
  • 因为它使用 GIO 事件 API,所以我们不会在每次更改语言时按两次 gsettings。我们让语言改变发生,因为它会一直发生。这使得在更改语言时速度更快,资源占用更少。
  • 因为它一直在倾听,所以我们永远不会等待 Python 穿上裤子并加载脚本。它在登录时加载一次,然后就可以进行更改了。
  • 因为它使用 API,任何其他改变输入语言(菜单图标、gsettings)的东西都会触发事件,从而触发这个脚本。

另一张海报的评论中有一些担忧,但虽然这是一个持久的脚本,但也对它有利。它消耗的微薄资源远远超过它会消耗百分之一的 RAM 的事实。

  • FWIW,我更喜欢这种方法。它并不适合所有情况,但我当然可以理解为什么要挂钩状态更改事件(而不是取代快捷方式)。我不确定我会在这里提出性能论据,因为我们实际上是在谈论毛发,并且正在进行的进程确实会占用 RAM,但是**我相信这 * 会* 响应更快** 如果事件通过 GIO像大多数事件循环一样接近实时。无论哪种方式,理论上都是如此。对这里关于性能的评论投反对票是非常严厉的。 (3认同)
  • 底线是:“消耗更少的资源”是主观的。我们在这里比较苹果和橙子。Jacob 的解决方案以内存为代价使用了更多的 CPU 和磁盘 I/O。Serg 使用更多内存,但会牺牲 CPU 和磁盘 I/O。 (2认同)

Jac*_*ijm 8

正在执行的文件?

恐怕切换源是Unity的内置功能,无法从外部用作cli选项。但是,这并不意味着我们无法完全实现您想要的目标。

将不断变化的布局与您的命令相结合的脚本化解决方案

替换原来的快捷方式

可以通过以下命令获取输入源:

gsettings get org.gnome.desktop.input-sources sources
Run Code Online (Sandbox Code Playgroud)

输出看起来像:

[('xkb', 'us+intl'), ('xkb', 'us'), ('xkb', 'nl'), ('xkb', 'be')]
Run Code Online (Sandbox Code Playgroud)

可以使用以下命令设置布局:

gsettings set org.gnome.desktop.input-sources current <index> 
Run Code Online (Sandbox Code Playgroud)

这样,我们可以用脚本版本替换键盘快捷键,以切换到下一种语言并同时运行您的命令。

剧本

gsettings get org.gnome.desktop.input-sources sources
Run Code Online (Sandbox Code Playgroud)

设置

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

    python3 /path/to/change_lang.py +
    
    Run Code Online (Sandbox Code Playgroud)

    和可选:

    python3 /path/to/change_lang.py -
    
    Run Code Online (Sandbox Code Playgroud)

    你的布局应该改变,你的命令应该运行。

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

    在此处输入图片说明

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

    python3 /path/to/change_lang.py +
    
    Run Code Online (Sandbox Code Playgroud)

    到您刚刚在步骤 2 中禁用的快捷方式。

    此外,您可以设置一个快捷方式以向相反方向移动(从列表中设置上一个源):

    python3 /path/to/change_lang.py -
    
    Run Code Online (Sandbox Code Playgroud)

就是这样。现在更改语言与您要运行的命令相结合。

它能做什么

资源

使用速度gsettings极低,并且通过将设置语言的命令与您的命令相结合,脚本仅在更改语言时运行

我相信这是最优雅的方式,虽然您不会在电费账单中注意到,但从长远来看,这是最低的资源。然而,在持续运行的进程、使用 API 或运行时调用选项之间的选择是一个品味问题。

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