Como atribuir permanentemente um layout de teclado diferente a um teclado USB?

14

Eu costumo plugar um teclado USB no meu laptop (além do monitor externo e do mouse, que praticamente convertem meu laptop em um computador de mesa) e prefiro usar um layout de teclado diferente.

Eu tenho que alterar manualmente o layout do teclado atual cada vez que eu plugin este teclado USB.

E eu gostaria de usar uma maneira automatizada para isso, se possível.

A resposta de Radu à questão aqui dá algumas dicas, mas parece que vou precisar de um script de inicialização para essa tarefa como o ID do dispositivo para meu USB o teclado muda sempre que o computador é iniciado.

Este script de inicialização provavelmente incluirá primeiro o comando xinput -list | grep "USB Keyboard" e outro comando para pegar o primeiro número de ID do Teclado USB exibido e usá-lo no comando final para definir o layout escolhido para o teclado USB conforme abaixo:

setxkbmap -device <NUMBER> -layout <LAYOUT>

    
por Sadi 26.08.2013 / 13:19

5 respostas

12

Após uma pequena pesquisa, encontrei uma solução, embora ainda esteja aberta a outras respostas (provavelmente melhores).

Aqui está um script de inicialização (que pode ser adicionado a Startup Applications ), que definirá a variável usbkbd_layout inserida pelo usuário usbkbd dispositivo id s encontrado no xinput -list :

#!/bin/bash
usbkbd='xinput -list | grep -c "USB Keyboard"'
if [[ "$usbkbd" -gt 0 ]]
then
    usbkbd_ids='xinput -list | grep "USB Keyboard" | awk -F'=' '{print $2}' | cut -c 1-2'
    usbkbd_layout="tr(f)"
    for ID in $usbkbd_ids
    do
      setxkbmap -device "${ID}" -layout "${usbkbd_layout}"
    done
fi
exit 0

Esse script é bastante útil (e mais estável) para cenários em que o usuário começa a usar o laptop em uma configuração de desktop (com teclado, mouse e monitor externos, etc.) e também pode ser executado manualmente sempre que o teclado USB externo está conectado ...

=============================================== ===========================

A MELHOR (quase perfeita) SOLUÇÃO - encontrada graças a MinimusHeximus e os respectivos contribuintes ao discussão ele mencionou em seu comentário abaixo:

Agora posso apenas plug-in meu teclado USB e ter seu layout de teclado diferente (TR-F) aplicado enquanto ainda mantém o layout de teclado padrão (TR-Q) no meu laptop!

Aqui estão os arquivos e seus conteúdos que tornam isso possível:

/etc/udev/rules.d/00-usb-keyboard.rules

ATTRS{idVendor}=="09da", ATTRS{idProduct}=="0260", OWNER="sadi"
ACTION=="add", RUN+="/home/sadi/.bin/usb-keyboard-in_udev"
ACTION=="remove", RUN+="/home/sadi/.bin/usb-keyboard-out_udev"

/home/sadi/.bin/usb-keyboard-in_udev

#!/bin/bash
/home/sadi/.bin/usb-keyboard-in &

/home/sadi/.bin/usb-keyboard-in

#!/bin/bash
sleep 1
DISPLAY=":0.0"
HOME=/home/sadi/
XAUTHORITY=$HOME/.Xauthority
export DISPLAY XAUTHORITY HOME
usbkbd_id='xinput -list | grep "USB Keyboard" | awk -F'=' '{print $2}' | cut -c 1-2 | head -1'
usbkbd_layout="tr(f)"
if [ "${usbkbd_id}" ]; then
    gsettings set org.gnome.settings-daemon.plugins.keyboard active false
    sleep 2
    setxkbmap -device "${usbkbd_id}" -layout "${usbkbd_layout}"
fi

/home/sadi/.bin/usb-keyboard-out_udev

#!/bin/bash
/home/sadi/.bin/usb-keyboard-out &

/home/sadi/.bin/usb-keyboard-out

#!/bin/bash
sleep 1
DISPLAY=":0.0"
HOME=/home/sadi/
XAUTHORITY=$HOME/.Xauthority
export DISPLAY XAUTHORITY HOME
gsettings set org.gnome.settings-daemon.plugins.keyboard active true

Notas:

  1. É claro que todos os quatro arquivos em sua pasta "bin" devem ter permissões necessárias (legíveis e executáveis) que talvez implementado por exemplo com um comando Terminal como chmod - 755 /home/sadi/.bin/usb-keyboard-*
  2. Às vezes, depois que o teclado USB é conectado, ele ainda usa o mesmo layout de teclado (padrão) e alterna para o layout especificado na segunda tentativa (talvez exigindo um pouco mais de tempo de suspensão em algum lugar)
  3. O layout específico do teclado USB não é efetivo na tela de login (quando você faz o logout).
  4. Se você usar uma partição separada para / home , talvez seja melhor colocar os quatro scripts em algum lugar na partição raiz, por exemplo, / usr / local / bin e modifique o conteúdo de todos os arquivos correspondentes, pois às vezes o udev pode procurar por esses arquivos antes que sua partição / home seja montada e cause problemas.

PARA ADAPTAR ESTA CONFIGURAÇÃO AOS REQUISITOS DIFERENTES:

    O fornecedor do teclado USB e os IDs do produto devem ser alterados de acordo com a saída do comando lsusb (Por exemplo, minha lsusb output tem isso para meu teclado USB: Bus 001 Device 006: ID 09da:0260 A4 Tech Co., Ltd )
  1. OWNER e todos os nomes de diretório de usuários devem ser alterados de "sadi" para outro nome
  2. O usbkbd_id pode exigir um pequeno ajuste para capturar o ID do dispositivo correto (por exemplo, a saída dos comandos xinput -list | grep "USB Keyboard" me fornece duas linhas; ↳ USB Keyboard id=14 [slave keyboard (3)] e ↳ USB Keyboard id=16 [slave keyboard (3)] ; que são filtradas por awk usando "="como delimitador de campo e capturando a segunda parte; em seguida, cortando apenas os dois primeiros dígitos e, em seguida, usando apenas o valor na primeira linha)
  3. O valor para usbkbd_layout pode ser qualquer outra opção válida
por Sadi 26.08.2013 / 14:39
5

Pode-se especificar opções do driver X11 dentro da regra do udev, não são necessários scripts personalizados. Por exemplo, aqui está o conteúdo do meu /etc/udev/rules.d/99-usb-kbd.rules

ACTION=="add", ATTRS{idVendor}=="04d9", ATTRS{idProduct}=="2323", ENV{XKBMODEL}="pc104", ENV{XKBLAYOUT}="us", ENV{XKBVARIANT}="euro", ENV{XKBOPTIONS}="compose:caps"

Esta regra garante que um teclado USB específico use o layout americano no Xorg (o teclado interno do meu laptop é o alemão, e esse também é meu layout principal). Pontos importantes:

  1. Você pode descobrir idVendor e idProduct do seu dispositivo usando lsusb ou evtest
  2. Você pode usar qualquer layout de /usr/share/X11/xkb/symbols . Preste atenção para especificar um layout válido e uma variante válida.
  3. O nome do arquivo deve começar com um número > 64 para que as configurações sobreponham as configurações do sistema especificadas em /lib/udev/rules.d/64-xorg-xkb.rules
  4. Certifique-se de que o gerenciamento de layout do Gnome / KDE não substitua suas configurações.
por pavel 07.08.2016 / 23:33
2

Acabei de melhorar esta solução para um teclado bépo Typematrix (versão francesa do dvorak excelente otimizado) e em um contexto de sistema amplo (supõe-se que você tenha acesso root à máquina). Precisa de apenas 3 arquivos para funcionar. Você pode consultar um arquivo de log em caso de falha para descobrir o que está falhando.

/etc/udev/96-usb-keyboard.rules

ATTRS{idVendor}=="1e54", ATTRS{idProduct}=="2030", SUBSYSTEMS=="usb", ACTION=="add", RUN+="/etc/udev/bepo-typematrix-kbd.sh in"
ATTRS{idVendor}=="1e54", ATTRS{idProduct}=="2030", SUBSYSTEMS=="usb", ACTION=="remove", RUN+="/etc/udev/bepo-typematrix-kbd.sh out"

/etc/udev/bepo-typematrix-kbd.sh (é absolutamente necessário usar um script intermediário de background)

#!/bin/bash

dir=$(dirname $0)
command=$(basename $0)
command=$dir/${command%\.sh}
arg=$1 # must be "in" or "out"
LOG=/var/log/bepo-typematrix-kbd.log

[ -x "$command" ] && $command $arg >$LOG 2>&1 &

/ etc / udev / bepo-typematrix-kbd

#!/bin/bash
# jp dot ayanides at free.fr

MODEL="tm2030USB-102" # keyboard model
DISPLAY=':0.0'
GSETTING=/usr/bin/gsettings
XSET=/usr/bin/xset
SETXKBMAP=/usr/bin/setxkbmap
XINPUT=/usr/bin/xinput

USER=$(/usr/bin/who | /usr/bin/awk -v DIS=':0' '{if ($2==DIS) print $1}')
eval HOME=~$USER
XAUTHORITY=$HOME/.Xauthority
export DISPLAY XAUTHORITY HOME

case $1 in
        'in')
                BEPO=$($XINPUT list --short | grep "TypeMatrix.com USB Keyboard" | grep keyboard | sed -e 's/^.*id=\([0-9]\+\).*//g')
                if [ -n "$BEPO" ]; then
                        [ -x $GSETTING ] && $GSETTING set org.gnome.settings-daemon.plugins.keyboard active false
                        # apparently nothing to do with TDE (trinity KDE)
                        for ID in $BEPO; do # case of multiple bepo keyboard is taken into account
                                [ -x $SETXKBMAP ] && $SETXKBMAP -device $ID -model $MODEL -layout fr -variant bepo
                        done
                fi
                echo "bépo keyboard id(s) is (are) $BEPO"
                [ -x $XSET ] && $XSET -display $DISPLAY r rate 250 40
        ;;
        'out')
                # apparently nothing to do with TDE (trinity KDE)
                [ -x $GSETTING ] && $GSETTING set org.gnome.settings-daemon.plugins.keyboard active true
        ;;
        *)
                printf "wrong parameter: $1\n"
                exit 1
        ;;
esac
    
por JP Ayanidès 10.01.2016 / 12:58
1

Depois de brincar muito, é por isso que estou correndo por agora. Talvez eu escreva um artigo completo e publique o código dentro de um repositório, se isso for de interesse.

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 for acionada por um dispositivo com a combinação específica 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 do udev:

sudo service udev restart

Observação: não consegui obter resultados confiáveis fornecendo regras de correspondência mais específicas nesse arquivo. Mais significativamente, a adição de uma regra de correspondência ACTION não funcionou. Tanto quanto eu posso dizer, o script foi acionado de qualquer maneira. Ao adicionar ACTION=="add" , o script ainda seria chamado após a remoção do dispositivo. Muito estranho e confuso.

No entanto, a ação que acionou a regra do udev estará disponível para o script chamado, conforme mostrado abaixo.

Em seguida, o script em si. Bem, não é bem assim. Observe o sufixo wrapper no nome do arquivo. Isso indica que este 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 usaremos isso 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 por seu ao definir a variável HOME ( $(whoami) não funcionará aqui, já que isso não será chamado pelo seu usuário, mas sim 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 remover esses.

Por fim, esses scripts precisam ter permissões de execução. Também pode ser importante observar que esses scripts serão chamados pelo usuário root , portanto, tenha cuidado com o que você faz lá.

chmod +x ~/.bin/switch-kb-layout-wrapper.sh ~/.bin/switch-kb-layout.sh 
    
por kleinfreund 23.07.2017 / 16:19
1

Eu tive algum problema de permissão com o script executado pelo udev. Eu resolvi com o sudo da seguinte forma:

# Estract id of MX3 keyboard devices that present themself as "123 COM Smart Control"
    IDLIST=$(sudo -u max /usr/bin/xinput -list | grep "123 COM Smart Control" | grep keyboard | sed -e 's/^.*id=\([0-9]\+\).*//g')

Definir o mapa do teclado para cada dispositivo

    for ID in $IDLIST; do
            sudo -u max /usr/bin/setxkbmap -device $ID -layout "${kb_layout}" -display :0
    done
    
por user835020 29.05.2018 / 00:54