O fim do suporte ao xneur trouxe-me certos sofrimentos nos últimos seis meses. (com a chegada do OpenSUSE 15.1 nos meus desktops: com o xneur ativado, as janelas perdem o foco e piscam divertidamente em sincronia com a digitação do teclado).
«Ah, droga, de novo comecei a digitar no layout errado» — isso acontece com uma frequência absurda no meu trabalho. E não adiciona nada de positivo.

Ao mesmo tempo, eu (como engenheiro de design) consigo articular claramente o que quero. E eu queria (inicialmente do Punto Switcher e depois, graças ao Windows Vista, finalmente migrando para Linux, do xneur) exatamente uma coisa. Percebendo que na tela havia uma confusão devido ao layout errado (isso geralmente acontece no final da digitação de uma nova palavra), dar um soco no 'Pause/Break'. E receber o que eu digitei.
Atualmente, o produto tem uma relação funcionalidade/complexidade ótima (do meu ponto de vista). É hora de compartilhar.
TL.DR
A seguir virão várias particularidades técnicas, então primeiro — para os impacientes.
Atualmente, o seguinte comportamento está codificado:
- «Pause/Break»: apaga (Backspace) a última palavra, alterna o layout na janela ativa (entre 0 e 1) e digita novamente.
- «Ctrl esquerdo sem nada»: alterna o layout na janela ativa (entre 0 e 1).
- «Shift esquerdo sem nada»: ativa o layout nº 0 na janela ativa.
- «Shift direito sem nada»: ativa o layout nº 1 na janela ativa.
A partir deste momento, planejo customizar o comportamento. Sem feedback — não é interessante (já estou satisfeito). Acredito que no Habra haverá uma porcentagem suficiente de audiência com problemas semelhantes.
N.B. Como na versão atual o keylogger é anexado a "/dev/input/", o xswitcher deve ser executado com privilégios de root:
chown root:root xswitcher
chmod +xs xswitcherObserve: o proprietário do arquivo com suid deve ser root, pois quem é o proprietário — terá o suid ativado ao ser executado.
Paranoicos (eu não sou exceção) podem clonar de e compilar localmente. Aproximadamente assim:
go get "github.com/micmonay/keybd_event"
go get "github.com/gvalkov/golang-evdev"
### Cabeçalhos X11 para OpenSUSE/deb-based
zypper install libX11-devel libXmu-devel
apt-get install libx11-dev libxmu-dev
cd "x switcher/src/"
go build -o xswitcher -ldflags "-s -w" --tags static_all src/*.go
Adicionar autostart a gosto (dependendo do DE).
Funciona, "não pede muito" (≈30 segundos de CPU por dia, ≈12 MB em RSS).
Detalhes
Agora — detalhes.
Todo o repositório foi inicialmente dedicado ao meu projeto pessoal, e estou com preguiça de criar outro. Portanto, tudo está misturado (apenas em pastas) e coberto pela AGPL (‘patente ao contrário’).
O código do xswitcher foi escrito em golang, com mínimas inserções de C. A expectativa é que essa abordagem resulte em menos esforço (até agora é assim). Mantendo a possibilidade de conectar o que falta via cgo.
Os comentários no texto explicam de onde eu peguei cada coisa e por quê. Como o código do xneur não me ‘inspirou’, usei como ponto de partida. .
O uso de "/dev/input/" tem seus prós (tudo visível, incluindo a tecla pressionada com repetição automática) e contras. Os contras são:
- A repetição automática (eventos com o código “2”) não se correlaciona com a repetição via X.
- Não é possível ver a entrada através das interfaces X11 (por exemplo, o VNC funciona assim).
- É necessário ser root.
Por outro lado, é possível assinar eventos X através de “XSelectExtensionEvent()”. É possível conferir isso no . Para Go, não encontrei nada parecido, e a implementação preliminar resultou em uma centena de linhas de código em C. Por enquanto, deixei de lado.
A saída ‘reversa’ foi feita através da adição de um teclado virtual. Agradeço ao autor do keybd_event, mas lá a abstração é muito alta e isso terá que ser refeito. No meu caso, por exemplo, a tecla Win direita seleciona a terceira linha. E a esquerda só transmite de volta.
Erros conhecidos
- Não sei nada sobre a entrada ‘compositiva’ (exemplo: ½). Atualmente, isso não é necessário.
- Estamos reproduzindo incorretamente a tecla Win direita. No meu caso, isso interfere na disposição dos acentos.
- Não há uma análise clara da entrada. Em vez disso, há várias funções: Compare(), CtrlSequence(), RepeatSequence(), SpaceSequence(). Obrigado pela atenção: corrigi no código e aqui. Há uma certa probabilidade de encontrar bugs durante a troca.
Neste ponto, não sei ‘como deve ser’ e ficarei feliz com qualquer sugestão. - (Oh horror) uso concorrente de canais (keyboardEvents, miceEvents).
Conclusão
O código é um simples procedimental. E é tão burro quanto eu. Portanto, me consolo na esperança de que qualquer técnico competente consiga completar o desejado. E que este produto, por isso, não desapareça sem suporte como a maioria dos projetos just-for-fun.
Boa sorte!
Fonte: habr.com
