web-dev-qa-db-fra.com

Comment attribuer en permanence une disposition de clavier différente à un clavier USB?

Je branche souvent un clavier USB sur mon ordinateur portable (en plus d'un moniteur externe et d'une souris, qui convertissent tous virtuellement mon ordinateur portable en un ordinateur de bureau) et je préfère alors utiliser une disposition de clavier différente.

Je dois modifier manuellement la disposition actuelle du clavier à chaque fois que je branche ce clavier USB.

Et j'aimerais utiliser un moyen automatisé pour cela, si possible.

La réponse de Rad à la question ici donne quelques indices, mais il semble que j'aurai besoin d'un script de démarrage pour cette tâche car l'ID de périphérique de mon clavier USB change à chaque démarrage de l'ordinateur.

Ce script de démarrage comportera probablement d’abord la commande xinput -list | grep "USB Keyboard", puis une autre commande permettant de saisir le premier numéro d’ID de clavier USB affiché, puis de l’utiliser dans la dernière commande pour définir la disposition de mon clavier USB comme indiqué ci-dessous:

setxkbmap -device <NUMBER> -layout <LAYOUT>

16
Sadi

Après quelques recherches, j'ai trouvé une solution, même si je suis toujours ouvert à d'autres réponses (probablement meilleures).

Voici un script de démarrage (qui peut être ajouté à Applications de démarrage) qui définira la variable saisie manuellement sbkbd_layout ​​à la variable sbkbd device id trouvé dans la 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

Ce script est très utile (et plus stable) pour les scénarios dans lesquels l'utilisateur commence à utiliser l'ordinateur portable sur une configuration de bureau (avec un clavier, une souris et un moniteur externes, etc.), et peut également être exécuté manuellement chaque fois que le clavier USB externe est branché. ...

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

LA MEILLEURE (presque parfaite) SOLUTION - trouvée grâce à MinimusHeximus et aux contributeurs respectifs du fil il a mentionné dans son commentaire ci-dessous:

Je peux maintenant simplement brancher mon clavier USB et automatiquement appliquer sa disposition de clavier différente (TR-F) tout en conservant la disposition de clavier par défaut (TR-Q) sur mon ordinateur portable!

Voici les fichiers et leur contenu qui rendent cela possible:

/ 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

Notes:

  1. Bien sûr, les quatre fichiers de votre dossier. "Bin" doivent disposer des autorisations nécessaires (lisibles et exécutables) pouvant être implémentées, par exemple, avec une commande Terminal telle que chmod - 755 /home/sadi/.bin/usb-keyboard-*
  2. Parfois, une fois le clavier USB branché, il utilise toujours la même disposition de clavier (par défaut) et bascule sur la disposition spécifiée lors du deuxième essai (nécessitant peut-être un peu plus de temps de sommeil quelque part?)
  3. La disposition spécifique du clavier USB n'est pas effective dans l'écran de connexion (lorsque vous vous déconnectez).
  4. Si vous utilisez une partition distincte pour / home, il serait peut-être préférable de placer les quatre scripts quelque part dans la partition racine, par exemple. / usr/local/bin et modifiez le contenu de tous les fichiers respectifs en conséquence, car parfois udev peut rechercher ces fichiers avant que votre partition / home ne soit montée et pose problème.

POUR ADAPTER CETTE CONFIGURATION À DIFFÉRENTES EXIGENCES:

  1. Les identifiants de fournisseur et de produit du clavier USB doivent être modifiés conformément à la sortie de la commande lsusb (par exemple, ma sortie lsusb a cette information pour mon clavier USB: Bus 001 Device 006: ID 09da:0260 A4 Tech Co., Ltd)
  2. Le propriétaire et tous les noms de répertoires d'utilisateurs doivent être changés de "sadi" à un autre nom
  3. Usbkbd_id peut nécessiter un petit ajustement pour récupérer le bon identifiant de périphérique (par exemple, la sortie des commandes xinput -list | grep "USB Keyboard" me donne deux lignes: ↳ USB Keyboard id=14 [slave keyboard (3)] et ↳ USB Keyboard id=16 [slave keyboard (3)]; elles sont ensuite filtrées par awk en utilisant "=" comme délimiteur de champ et en capturant la seconde partie; puis ne coupez que les deux premiers chiffres, puis utilisez uniquement la valeur de la première ligne)
  4. La valeur de usbkbd_layout peut être un autre choix valide.
15
Sadi

On peut spécifier les options du pilote X11 dans la règle udev, aucun script personnalisé n’est nécessaire. À titre d’exemple, voici le contenu de mon / 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"

Cette règle garantit qu'un clavier USB particulier utilise la présentation des États-Unis dans Xorg (le clavier interne de mon ordinateur portable est allemand et il s'agit également de ma présentation principale). Les points importants:

  1. Vous pouvez trouver idVendoret idProductde votre appareil en utilisant lsusbou evtestname__
  2. Vous pouvez utiliser n’importe quelle disposition à partir de /usr/share/X11/xkb/symbols. Faites attention à spécifier une présentation valide et une variante valide.
  3. Le nom de fichier doit commencer par un nombre supérieur à 64 pour que les paramètres remplacent les paramètres système définis dans /lib/udev/rules.d/64-xorg-xkb.rules
  4. Assurez-vous que la gestion de la présentation Gnome/KDE ne remplace pas vos paramètres.
9
pavel

Je viens d’améliorer cette solution pour un clavier bépo Typematrix (version française d’excellent dvorak optimisé) et dans un contexte système étendu (cela suppose que vous ayez un accès root à la machine). Il ne faut que 3 fichiers pour fonctionner. Vous pouvez consulter un fichier journal en cas d'échec pour déterminer ce qui échoue.

/ 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 (absolument nécessaire d'utiliser un script d'arrière-plan intermédiaire)

#!/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]\+\).*/\1/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
2
JP Ayanidès

Après avoir beaucoup bricolé, voici ce que je cours pour le moment. J'écrirai peut-être un article complet et publierai le code dans un référentiel, si cela peut vous intéresser.


Configurez un nouveau jeu de règles pour udev comme ceci:

 Sudo gedit /etc/udev/rules.d/80-external-keyboard.rules

La règle est supposée appeler un script Shell chaque fois qu'une action est déclenchée par un périphérique avec la combinaison donnée d'ID de fournisseur et de produit.

ATTRS{idVendor}=="04b4", ATTRS{idProduct}=="4042", RUN+="/home/phil/.bin/switch-kb-layout-wrapper.sh"

Après avoir ajouté le nouvel ensemble de règles, redémarrez le service udev:

Sudo service udev restart

Remarque: Je n'ai pas pu obtenir de résultats fiables en fournissant des règles de correspondance plus spécifiques dans ce fichier. Plus important encore, l'ajout d'une règle de correspondance ACTION n'a pas fonctionné. Autant que je sache, le script a quand même été déclenché. Lors de l'ajout de ACTION=="add", le script serait toujours appelé lors de la suppression du périphérique. Très étrange et déroutant.

Cependant l'action qui a déclenché la règle udev sera disponible pour le script appelé, comme indiqué ci-dessous.


Ensuite, le script lui-même. Pas tout à fait. Notez le suffixe wrapper dans le nom du fichier. Cela indique qu'il ne s'agit pas du script lui-même mais d'un wrapper qui appelle le script et l'exécute en arrière-plan afin que udev puisse achever son processus.

~/.bin/switch-kb-layout-wrapper.sh:

#!/bin/sh
/home/phil/.bin/switch-kb-layout.sh "${ACTION}" &

La variable ACTION contient l'action udev déclenchée par le périphérique. Il génère des valeurs telles que add (le périphérique a été branché) et remove (le périphérique a été supprimé). Nous les utiliserons plus tard.

~/.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

Remplacez mon nom d’utilisateur par le vôtre lors de la définition de la variable HOME ($(whoami) ne fonctionnera pas ici, car il ne sera pas appelé par votre utilisateur mais par root).

sed -i "s/phil/YOUR_USERNAME/g" ~/.bin/switch-kb-layout.sh

À des fins de test, j'ai ajouté quelques lignes qui enregistrent certains événements dans un fichier de mon répertoire personnel pour voir si tout fonctionne. Vous pouvez les supprimer en toute sécurité.


Enfin, ces scripts doivent avoir des autorisations d'exécution. De plus, il peut être important de noter que ces scripts seront appelés par l'utilisateur root, soyez donc prudent dans ce que vous faites.

chmod +x ~/.bin/switch-kb-layout-wrapper.sh ~/.bin/switch-kb-layout.sh 
1
kleinfreund

J'ai eu un problème de permission avec le script exécuté par udev. J'ai résolu avec Sudo comme suit:

# 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]\+\).*/\1/g')

Définir la carte du clavier pour chaque périphérique

    for ID in $IDLIST; do
            Sudo -u max /usr/bin/setxkbmap -device $ID -layout "${kb_layout}" -display :0
    done
1
user835020