Comment attribuer définitivement une disposition de clavier différente à un clavier USB?

16

Je branche souvent un clavier USB à mon ordinateur portable (en plus du moniteur et de la souris externes, qui convertissent tous virtuellement mon ordinateur portable en ordinateur de bureau) et je préfère utiliser une disposition de clavier différente.

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

Et j'aimerais utiliser une méthode automatisée pour cela, si possible.

La réponse de Radu à 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 inclura probablement d'abord la commande xinput -list | grep "USB Keyboard", et une autre commande pour saisir le premier numéro d'identification du clavier USB affiché, puis l'utiliser dans la commande finale pour définir la disposition choisie pour ce clavier USB comme ci-dessous:

setxkbmap -device <NUMBER> -layout <LAYOUT>

Sadi
la source
1
@Sadi Vous parlez de renverser les drapeaux des Rutgers et des États-Unis après l'assassinat du Dr Martin Luther King? Paul Robeson: The Great Forerunner par Freedomways à la page 182
guest271314
@ guest271314 Merci beaucoup! Mais je me demande comment vous vous êtes retrouvé ici pour commenter cette question: history.stackexchange.com/questions/48704/… ;-) C'est aussi une autre forme de protestation intelligente mais je ne pense pas que cela pourrait éventuellement évoluer en histoire de ouï-dire, je me souviens.
Sadi
@Sadi Votre question a été supprimée à Politics.
guest271314

Réponses:

15

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é à des applications de démarrage ) , qui fixera la saisie maually usbkbd_layout variable au usbkbd dispositif ID de la Trouvées de 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 où l'utilisateur commence à utiliser l'ordinateur portable sur une configuration de bureau (avec clavier, souris et moniteur externes, etc.), et il 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 au fil qu'il a mentionné dans son commentaire ci-dessous:

Je peux maintenant simplement brancher mon clavier USB et appliquer automatiquement 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

Remarques:

  1. Bien sûr, les quatre fichiers de votre dossier "bin" doivent avoir les autorisations nécessaires (lisibles et exécutables) qui peuvent être implémentées par exemple avec une commande Terminal comme 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 passe à 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 efficace dans l'écran de connexion (lorsque vous vous déconnectez).
  4. Si vous utilisez une partition distincte pour / home , il peut être préférable de placer les quatre scripts quelque part dans la partition racine, par exemple / usr / local / bin et de modifier 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 causent des problèmes.

AFIN D'ADAPTER CETTE CONFIGURATION AUX DIFFÉRENTES EXIGENCES:

  1. Fournisseur clavier USB et de produits ids doivent être modifiés selon la sortie de la commande lsusb(par exemple, ma lsusbsortie ont pour mon clavier USB: Bus 001 Device 006: ID 09da:0260 A4 Tech Co., Ltd)
  2. PROPRIÉTAIRE et tous les noms de répertoires d'utilisateurs doivent être modifiés de "sadi" à un autre nom
  3. Le usbkbd_id peut nécessiter un petit ajustement pour saisir l'ID de périphérique correct (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)]; qui sont ensuite filtrées en awkutilisant "=" comme délimiteur de champ et en capturant la deuxième partie; puis en coupant uniquement le deux premiers chiffres, puis en utilisant uniquement la valeur de la première ligne)
  4. La valeur de usbkbd_layout peut être tout autre choix valide
Sadi
la source
Ce serait formidable si un autre script similaire pouvait s'exécuter automatiquement chaque fois qu'un clavier USB est branché, comme demandé (pas encore répondu) ici: askubuntu.com/questions/284224/…
Sadi
2
Il peut être utile si vous pouvez poster une autre réponse à partir de ce fil de discussion en désordre: superuser.com/questions/249064/…
nano - me fusionner
1
@MinimusHeximus Merci mille fois !!! Après avoir parcouru le fil que vous avez souligné et fait quelques essais et erreurs, je l'ai finalement trié et ajouterai cette nouvelle (presque) parfaite solution de branchement à chaud ci-dessus!
Sadi
1
Mon clavier pour deux raisons a deux identifiants, donc au lieu d'utiliser un IFj'ai dû utiliser un FOR. Cela fonctionne pour moi maintenant, merci! gist.github.com/zvictor/193b567c14b5b6a679fe
zVictor
1
@Sadi, je suis moi-même un simple utilisateur moyen. Je posterai ma solution ici. Vous pouvez peut-être en retirer quelques idées.
kleinfreund
9

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 disposition américaine dans Xorg (le clavier interne de mon ordinateur portable est allemand, et c'est également ma disposition principale). Les points importants:

  1. Vous pouvez découvrir idVendoret connaître idProductvotre appareil en utilisant lsusbouevtest
  2. Vous pouvez utiliser n'importe quelle mise en page à partir de /usr/share/X11/xkb/symbols. Faites attention à spécifier à la fois une mise en page valide et une variante valide.
  3. Le nom du fichier doit commencer par un nombre> 64 pour que les paramètres écrasent les paramètres à l'échelle du système spécifiés dans /lib/udev/rules.d/64-xorg-xkb.rules
  4. Assurez-vous que la gestion de la mise en page Gnome / KDE n'écrase pas vos paramètres.
pavel
la source
Débranchez et rebranchez votre clavier et recherchez /var/log/Xorg.0.logd'éventuels problèmes. Vous pouvez également utiliser udevadm infopour vérifier que les paramètres sont appliqués correctement.
pavel
Eureka! Votre solution intelligente a commencé à travailler seulement après je suis entré dans cette commande (une fois pour toutes) pour remplacer le paramètre gconf actuel: gsettings set org.gnome.settings-daemon.plugins.keyboard active false. Si vous ajoutez également une telle note, je vais essayer de marquer la vôtre comme la réponse (au lieu de cette route maladroite, longue et sinueuse ;-)
Sadi
C'est exceptionnel. Sur Ubuntu 14.04, les modèles / dispositions / options / etc possibles. sont listés à/usr/share/X11/xkb/rules/evdev.lst
Jon
2
Malheureusement, cette solution agréable et facile a cessé de fonctionner pour moi après la mise à niveau vers Ubuntu Gnome 17.04 :-(
Sadi
Essayé Linux Mint 18.2, qui est basé sur Ubuntu 16.04 LTS, avec la version udev 229-4ubuntu19 , sans effet à nouveau :-( Des idées sur ce comportement étrange udev ???
Sadi
2

Je viens d'améliorer cette solution pour un clavier bépo Typematrix (version française d'un excellent dvorak optimisé) et dans un contexte système large (cela suppose que vous ayez un accès root à la machine). Il n'a besoin que de 3 fichiers pour fonctionner. Vous pouvez consulter un fichier journal en cas d'échec pour comprendre 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 pour 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
JP Ayanidès
la source
1

Après avoir beaucoup tripoté, c'est ce que j'ai pour l'instant. Je vais peut-être écrire un article complet et publier le code dans un référentiel, si cela vous intéresse.


Configurez un nouvel ensemble de règles pour udev comme celui-ci:

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

La règle est censée appeler un script shell chaque fois qu'une action est déclenchée par un appareil 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 ACTIONrègle de correspondance n'a pas fonctionné. Autant que je sache, le script a quand même été déclenché. Lors de l'ajout ACTION=="add", le script sera 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. Enfin, pas tout à fait. Notez le wrappersuffixe dans le nom de fichier. Cela indique qu'il ne s'agit pas du script réel mais d'un wrapper qui appelle le script et l'exécute en arrière-plan afin que udev puisse terminer son processus.

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

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

La variable ACTIONcontient l'action udev déclenchée par le périphérique. Il donne des valeurs comme 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 HOMEvariable ( $(whoami)ne fonctionnera pas ici, car cela 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. Il peut également être important de noter que ces scripts seront appelés par l' rootutilisateur, alors faites attention à ce que vous y faites.

chmod +x ~/.bin/switch-kb-layout-wrapper.sh ~/.bin/switch-kb-layout.sh 
kleinfreund
la source
1
Merci, bon travail! Je l'ai aussi bien. Cependant, pourquoi je vois 14 fois "Ajouter une action" et 3 fois "Autre action" lorsque je branche ma commande externe est un mystère, que j'essaierai de résoudre plus tard. Mais j'ai trouvé qu'il est préférable d'ajouter également l'ID de périphérique à la commande setxkbmap afin que le clavier interne soit toujours utilisable ainsi que le clavier externe, comme dans mon dernier script de démarrage automatique. Je vais essayer ceci pendant quelques jours, et je reviendrai pour voir si la vôtre peut être considérée comme LA réponse, peut-être avec une petite modification ici et là ;-)
Sadi
Obtention également des mêmes lignes enregistrées plusieurs fois. Bonne capture sur l'ID de l'appareil sur la commande.
kleinfreund
@Sadi Je pense également que la ligne gsettings set org.gnome.settings-daemon.plugins.keyboard active falsene fonctionne pas comme prévu, car le script est exécuté par root. Dans mes tests, la ligne n'a pas eu d'effet sur ce paramètre.
kleinfreund
Je pense que dans un tel scénario, ce pourrait être une bonne idée d'exécuter la commande en gsettings set org.gnome.settings-daemon.plugins.keyboard active falsetant qu'utilisateur une fois pour toutes, puis d'utiliser ce script sans les gsettings setcommandes ...
Sadi
Jusqu'à présent, j'ai vu que nous ne pouvons toujours pas faire fonctionner cette chose sans problème; de temps en temps, la disposition du clavier n'est pas implémentée par udev, et vous devez vous déconnecter puis vous reconnecter. Je pense que je vais revenir à mon script de démarrage (mis à jour) en haut de ma réponse pendant un certain temps, ce qui me sert plus facilement - seulement je dois l'exécuter manuellement si je branche mon clavier externe après le démarrage. Il semble que udev soit un peu bogué comme on peut le voir dans tant de répétitions d'actions (il exécute le script wrapper plusieurs fois, et de manière étrange) ...
Sadi
1

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éfinissez la carte du clavier pour chaque appareil

    for ID in $IDLIST; do
            sudo -u max /usr/bin/setxkbmap -device $ID -layout "${kb_layout}" -display :0
    done
user835020
la source
Je pense que cela peut être plus utile si vous pouvez l'écrire en entier. Par exemple, où avez-vous mis les lignes ci-dessus?
Sadi
0

Vous pouvez également le définir dans un fichier de configuration Xorg.

Il est présenté dans cette réponse stackexchange: /superuser//a/946575/437492

Golar Ramblar
la source
Ce serait formidable, si je pouvais le faire fonctionner. Mais en utilisant la dernière version de LTS, Ubuntu 18.04, je ne peux voir que le répertoire /usr/share/X11/xorg.conf.d/ qui contient un fichier nommé 40-libinput.conf . J'ai donc simplement ajouté une section pour le clavier externe dans ce fichier. En utilisant le pilote libinput ou evdev et un nom de fournisseur de plus en plus court, je n'ai pu obtenir aucun résultat. Des idées?
Sadi
@Sadi: Si vous lisez un peu la configuration de Xorg, vous découvrirez que vous pouvez simplement ajouter de nouveaux fichiers /etc/X11/xorg.conf.d/(c'est l'endroit où aller).
Golar Ramblar
Merci. J'ai sûrement lu pas mal de choses et j'ai d'abord essayé d'utiliser "/etc/X11/xorg.conf.d/30-keyboard.conf". Je vais tenter ma chance sous la réponse stackexchange mentionnée ci-dessus. ;-)
Sadi