Como iniciar a execução automática de comandos na troca de layout de teclado?

6

Eu quero executar os seguintes comandos:

xmodmap -e "keycode 52=y"
xmodmap -e "keycode 29=z"

sempre que eu mudar o layout do meu teclado ( Shift + Alt ). Existe alguma maneira de fazer isso?

    
por huehuehuehuehuehuehuehuehuehue 08.02.2017 / 14:25

2 respostas

10

Como a comutação de idioma é implementada no Ubuntu

Por padrão, a fonte de entrada do Ubuntu é definida em um banco de dados chamado gsettings . Cada configuração tem um esquema específico associado a ela. Em particular, a alternância de idiomas está associada ao org.gnome.desktop.input-sources schema. Esse é o que estamos interessados em todas as versões modernas do Ubuntu.

Mais especificamente, estamos interessados em sua chave current . Quando você altera o idioma via GUI, essa chave é modificada. Há muitas coisas que você pode fazer com isso, de alternando o idioma de entrada na linha de comando para definindo atalhos para cada método de entrada , mesmo definindo o método de entrada para cada indivíduo app pode ser feito. Uma maneira de fazer isso é através do comando gsettings ou dconf . Estes são programas externos que vivem na sua pasta /usr/bin/ (este é o mesmo método que a resposta de Jacob usa). Outra maneira é através de um conjunto específico de utilitários (API, na verdade) para a linguagem de programação Python. Este é o método que mostrarei na minha resposta.

Deve-se notar que gsettings nem sempre funciona. Se você estiver usando um método de entrada não padrão, como fcitx , por exemplo, isso pode não ser verdade. De fato, o sogou-pinyin (método de entrada chinês) usa algo mais conhecido como dbus , então a abordagem com gsettings won não funciona. Mas para casos simples em que você tem o Ubuntu padrão, gsettings database é suficiente.

Detectando alteração do método de entrada

A maneira como Jacob faz isso é através de uma execução única do comando gsettings externo e modificando atalhos, de tal forma que cada vez que você clica no atalho, o programa é executado. Há outra abordagem, via API Gio já existente. Esse tipo de API seria usado quando você desenvolve um aplicativo de desktop apropriado para o Ubuntu ou outro sistema que usa o desktop relacionado ao GNOME. O script abaixo ilustra a abordagem com a API Gio .

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

Existem vantagens distintas para essa abordagem ao interferir nos atalhos:

  • Você não precisa editar os atalhos. Eu não vou exagerar, mas a configuração para esta resposta é apenas fazer o script iniciar automaticamente quando você faz o login .

    li>
  • Como ele usa a API de eventos da GIO, não estamos tagarelando nas configurações duas vezes toda vez que mudamos de idioma. Nós deixamos a mudança de idioma acontecer como sempre teria acontecido. Isso faz com que seja mais rápido e menos intensivo em termos de recursos ao alterar idiomas.
  • Como está sempre ouvindo, nunca esperamos que o Python coloque suas calças e carregue um script. Ele carrega uma vez, no login e pronto para alterações.
  • Como ele usa a API, qualquer outra outra que altere o idioma de entrada (ícones de menu, gsettings) ativará o evento e, portanto, esse script.

Existem algumas preocupações nos comentários do outro pôster, mas embora este seja um script persistente, ele também trabalha a seu favor. Os escassos recursos que consomem superam em muito o fato de que ele consome uma fração de um percentual de RAM.

    
por Sergiy Kolodyazhnyy 09.02.2017 / 02:03
8

Um arquivo sendo executado?

Eu tenho medo que as fontes de chaveamento sejam construídas em função do Unity, que não está disponível como uma opção cli de fora. No entanto , isso não significa que não temos opções para alcançar exatamente o que você deseja.

Solução com script para combinar a mudança de layout com seu comando

Substituindo o atalho original

Fontes de entrada podem ser buscadas pelo comando:

gsettings get org.gnome.desktop.input-sources sources

A saída parece:

[('xkb', 'us+intl'), ('xkb', 'us'), ('xkb', 'nl'), ('xkb', 'be')]

O layout pode ser definido com o comando:

gsettings set org.gnome.desktop.input-sources current <index> 

Dessa forma, podemos substituir o atalho de teclado por uma versão com script para alternar para o próximo idioma e executar seu comando ao mesmo tempo.

O script

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

Configurar

  1. Copie o script em um arquivo vazio, salve-o como change_lang.py
  2. Teste- execute o script pelo comando:

    python3 /path/to/change_lang.py +
    

    e, opcionalmente:

    python3 /path/to/change_lang.py -
    

    Seu layout deve mudar e seus comandos devem ser executados.

  3. Se tudo funcionar bem, abra as Configurações do sistema, vá para "Teclado" > "Atalhos" > "Digitando". Clique no atalho para alternar a fonte (à direita, para definir o atalho) e pressione backspace para desativar o atalho.

  4. Agora,adicioneomesmoatalhoaosatalhospersonalizados:escolha:Configuraçõesdosistema>"Teclado" > "Atalhos" > "Atalhos personalizados". Clique no botão "+" e adicione o comando:

    python3 /path/to/change_lang.py +
    

    Para o atalho que você acabou de desativar na etapa 2.

    Além disso, você pode definir um atalho para se mover ao contrário (definir fonte anterior da lista):

    python3 /path/to/change_lang.py -
    

É isso. Agora, a mudança de idioma é combinada com o comando que você deseja executar.

O que faz

  • Sempre que seu atalho é pressionado, o script é chamado, procurando qual é o idioma atual, pelo comando:

    gsettings get org.gnome.desktop.input-sources current
    
  • O script subseqüentemente se move para o próximo, ou o anterior, dependendo do argumento, pelo comando:

    gsettings set org.gnome.desktop.input-sources current <index>
    

Recursos

Usar gsettings é extremamente baixo em suco, e combinando o comando para definir o idioma com seus comandos, o script só é executado ao alterar o idioma .

Eu acredito que é a maneira mais elegante e, embora você não perceba em sua conta de energia elétrica, a longo prazo, o menor dos recursos. A escolha entre um processo em constante execução, usando a API, ou uma opção de execução quando chamada é uma questão de gosto, no entanto.

Observe também que o script primeiro altera o idioma e, em seguida, executa os outros comandos. Não há diferença perceptível na resposta nas duas respostas.

    
por Jacob Vlijm 08.02.2017 / 19:49