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>
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:
chmod - 755 /home/sadi/.bin/usb-keyboard-*
POUR ADAPTER CETTE CONFIGURATION À DIFFÉRENTES EXIGENCES:
lsusb
(par exemple, ma sortie lsusb
a cette information pour mon clavier USB: Bus 001 Device 006: ID 09da:0260 A4 Tech Co., Ltd
)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)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:
idVendor
et idProduct
de votre appareil en utilisant lsusb
ou evtest
name__/usr/share/X11/xkb/symbols
. Faites attention à spécifier une présentation valide et une variante valide./lib/udev/rules.d/64-xorg-xkb.rules
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
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
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')
for ID in $IDLIST; do
Sudo -u max /usr/bin/setxkbmap -device $ID -layout "${kb_layout}" -display :0
done