Depois de mexer bastante, é para isso que eu tenho agora. Talvez eu escreva um artigo completo e publique o código em um repositório, se isso for interessante.
Configure um novo conjunto de regras para o udev assim:
sudo gedit /etc/udev/rules.d/80-external-keyboard.rules
A regra deve chamar um script de shell sempre que alguma ação é acionada por um dispositivo com a combinação fornecida de fornecedor e ID do produto.
ATTRS{idVendor}=="04b4", ATTRS{idProduct}=="4042", RUN+="/home/phil/.bin/switch-kb-layout-wrapper.sh"
Após adicionar o novo conjunto de regras, reinicie o serviço udev:
sudo service udev restart
Nota: Não consegui obter resultados confiáveis fornecendo regras de correspondência mais específicas nesse arquivo. Mais significativamente, a adição de uma ACTION
regra de correspondência não funcionou. Até onde eu sei, o script foi acionado de qualquer maneira. Ao adicionar ACTION=="add"
, o script ainda seria chamado ao remover o dispositivo. Muito estranho e confuso.
No entanto, a ação que acionou a regra do udev estará disponível para o script chamado, como mostrado abaixo.
Em seguida, o próprio script. Bem, não exatamente. Anote o wrapper
sufixo no nome do arquivo. Isso indica que esse não é o script real, mas um wrapper que chama o script e o executa em segundo plano para que o udev possa concluir seu processo.
~/.bin/switch-kb-layout-wrapper.sh
:
#!/bin/sh
/home/phil/.bin/switch-kb-layout.sh "${ACTION}" &
A variável ACTION
contém a ação do udev que foi acionada pelo dispositivo. Ele gera valores como add
(o dispositivo foi conectado) e remove
(o dispositivo foi removido). Nós os usaremos mais tarde.
~/.bin/switch-kb-layout.sh
:
#!/bin/sh
sleep 1
# Some environment variables that need to be set in order to run `setxkbmap`
DISPLAY=":0.0"
HOME=/home/phil
XAUTHORITY=$HOME/.Xauthority
export DISPLAY XAUTHORITY HOME
udev_action=$1
log_file="$HOME/switch-kb-layout.log"
if [ "${udev_action}" != "add" ] && [ "${udev_action}" != "remove" ]; then
echo "Other action. Aborting." >> $log_file
exit 1
fi
internal_kb_layout="de"
internal_kb_variant=""
external_kb_layout="us"
external_kb_variant="altgr-intl"
kb_layout=""
kb_variant=""
if [ "${udev_action}" = "add" ]; then
kb_layout=$external_kb_layout
kb_variant=$external_kb_variant
elif [ "${udev_action}" = "remove" ]; then
kb_layout=$internal_kb_layout
kb_variant=$internal_kb_variant
fi
setxkbmap -layout "${kb_layout}"
echo "set layout:" "$kb_layout" >> $log_file
if [ ! -z "${kb_variant}" ]; then
setxkbmap -variant "${kb_variant}"
echo "set variant:" "$kb_variant" >> $log_file
fi
Substitua meu nome de usuário pelo seu ao definir a HOME
variável ( $(whoami)
não funcionará aqui, pois isso não será chamado pelo usuário, mas por root
).
sed -i "s/phil/YOUR_USERNAME/g" ~/.bin/switch-kb-layout.sh
Para fins de teste, adicionei algumas linhas que registram determinados eventos em um arquivo no meu diretório pessoal para ver se tudo funciona. Você pode removê-los com segurança.
Finalmente, esses scripts precisam ter permissões de execução. Também pode ser importante observar que esses scripts serão chamados pelo root
usuário, portanto, tenha cuidado com o que você faz lá.
chmod +x ~/.bin/switch-kb-layout-wrapper.sh ~/.bin/switch-kb-layout.sh