Come assegnare in modo permanente un diverso layout di tastiera a una tastiera USB?


16

Collego spesso una tastiera USB al mio laptop (oltre al monitor e al mouse esterni, che praticamente convertono il mio laptop in un computer desktop) e preferisco quindi utilizzare un layout di tastiera diverso.

Devo modificare manualmente il layout corrente della tastiera ogni volta che inserisco questa tastiera USB.

E mi piacerebbe usare un modo automatizzato per questo, se possibile.

La risposta di Radu alla domanda qui fornisce alcuni indizi, ma sembra che avrò bisogno di uno script di avvio per questa attività poiché l'ID del dispositivo per la mia tastiera USB cambia ogni volta che si avvia il computer.

Questo script di avvio includerà probabilmente prima il comando xinput -list | grep "USB Keyboard"e un altro comando per afferrare il primo numero ID tastiera USB visualizzato e quindi utilizzarlo nel comando finale per impostare il layout scelto per quella tastiera USB come di seguito:

setxkbmap -device <NUMBER> -layout <LAYOUT>



1
@Sadi Ti riferisci a capovolgere Rutgers e le bandiere americane dopo l'assassinio del Dr. Martin Luther King? Paul Robeson: The Great Forerunner di Freedomways a pagina 182
guest271314

@ guest271314 Grazie mille! Ma mi chiedo come mai sei finito qui per commentare questa domanda: history.stackexchange.com/questions/48704/… ;-) Questa è anche un'altra forma intelligente di protesta, ma non credo che questo potrebbe eventualmente evolversi nel ascolta la storia che ricordo.
Sadi,

@Sadi La tua domanda è stata cancellata in Politica.
ospite271314

Risposte:


15

Dopo una piccola ricerca, ho trovato una soluzione, anche se sono ancora aperto ad altre (probabilmente migliori) risposte.

Ecco uno script di avvio (che può essere aggiunto alle applicazioni di avvio ) che imposterà la variabile usbkbd_layout immessa manualmente sugli ID dispositivo usbkbd presenti nell'elenco- xinput :

#!/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

Questo script è abbastanza utile (e più stabile) per gli scenari in cui l'utente inizia a utilizzare il laptop su un'impostazione desktop (con tastiera, mouse e monitor esterni, ecc.) E può anche essere eseguito manualmente ogni volta che viene collegata la tastiera USB esterna ...

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

LA MIGLIORE (quasi perfetta) SOLUZIONE - trovata grazie a MinimusHeximus e ai rispettivi collaboratori alla discussione che ha citato nel suo commento qui sotto:

Ora posso solo collegare la mia tastiera USB e applicare automaticamente il suo diverso layout di tastiera (TR-F) mantenendo il layout di tastiera predefinito (TR-Q) sul mio laptop!

Ecco i file e i loro contenuti che lo rendono possibile:

/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

Appunti:

  1. Naturalmente tutti e quattro i file nella cartella "bin" dovrebbero avere le autorizzazioni necessarie (leggibili ed eseguibili) che potrebbero essere implementate ad esempio con un comando Terminale come chmod - 755 /home/sadi/.bin/usb-keyboard-*
  2. A volte, dopo aver collegato la tastiera USB, utilizza ancora lo stesso layout di tastiera (predefinito) e passa al layout specificato al secondo tentativo (forse richiede un po 'più di tempo di sonno da qualche parte?)
  3. Il layout specifico della tastiera USB non è efficace nella schermata di accesso (quando ci si disconnette).
  4. Se usi una partizione separata per / home , allora potrebbe essere una buona idea mettere i quattro script da qualche parte nella partizione root, ad esempio / usr / local / bin e modificare il contenuto di tutti i rispettivi file di conseguenza, come talvolta udev può cercare quei file prima che la tua partizione / home sia montata e causi problemi.

AL FINE DI ADATTARE QUESTA CONFIGURAZIONE A DIVERSI REQUISITI:

  1. Tastiera USB vendor e product ids devono essere cambiati secondo l'output del comando lsusb(ad esempio, la lsusbproduzione ha questo per la mia tastiera USB: Bus 001 Device 006: ID 09da:0260 A4 Tech Co., Ltd)
  2. Il PROPRIETARIO e tutti i nomi delle directory degli utenti devono essere cambiati da "sadi" a un altro nome
  3. Usbkbd_id potrebbe richiedere un piccolo aggiustamento per afferrare l'id del dispositivo corretto (ad esempio, l'output dei comandi xinput -list | grep "USB Keyboard"mi dà due righe; ↳ USB Keyboard id=14 [slave keyboard (3)]e ↳ USB Keyboard id=16 [slave keyboard (3)]; che vengono quindi filtrati awkusando "=" come delimitatore di campo e catturando la seconda parte; quindi tagliando solo il prime due cifre, quindi utilizzando solo il valore nella prima riga)
  4. Il valore per usbkbd_layout può essere qualsiasi altra scelta valida

Sarebbe bello se un altro script simile potesse essere eseguito automaticamente ogni volta che una tastiera USB è collegata, come richiesto (non ancora risposto) qui: askubuntu.com/questions/284224/…
Sadi

2
Può essere utile se puoi pubblicare un'altra risposta da questo thread disordinato: superuser.com/questions/249064/…
nano - uniscimi

1
@MinimusHeximus Grazie mille !!! Dopo aver esaminato il thread che hai sottolineato e aver fatto qualche prova, ho finalmente risolto il problema e aggiungerò sopra questa nuova soluzione (quasi) perfetta di hotplugging!
Sadi,

1
La mia tastiera per qualche motivo ha due ID, quindi invece di usare un IFho dovuto usare un FOR. Funziona per me ora, grazie! gist.github.com/zvictor/193b567c14b5b6a679fe
zVictor

1
@Sadi Sono anche io un semplice utente medio. Pubblicherò la mia soluzione qui. Forse puoi toglierti alcune idee.
Kleinfreund,

9

È possibile specificare le opzioni del driver X11 all'interno della regola udev, non sono necessari script personalizzati. Ad esempio, ecco i contenuti del mio /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"

Questa regola assicura che una particolare tastiera USB utilizzi il layout americano in Xorg (la tastiera interna del mio laptop è tedesca, e questo è anche il mio layout principale). Punti importanti:

  1. Puoi scoprire idVendore idProductdel tuo dispositivo usando lsusboevtest
  2. È possibile utilizzare qualsiasi layout da /usr/share/X11/xkb/symbols. Prestare attenzione a specificare sia un layout valido sia una variante valida.
  3. Il nome del file deve iniziare con un numero> 64 per consentire alle impostazioni di sovrascrivere le impostazioni di sistema specificate in /lib/udev/rules.d/64-xorg-xkb.rules
  4. Assicurati che la gestione del layout di Gnome / KDE non sovrascriva le tue impostazioni.

Scollegare e ricollegare la tastiera e cercare /var/log/Xorg.0.logeventuali problemi. Puoi anche usare udevadm infoper verificare che le impostazioni siano applicate correttamente.
padiglione

Eureka! La soluzione intelligente ha iniziato a lavorare solo dopo che sono entrato questo comando (una volta per tutte) per ignorare l'impostazione gconf corrente: gsettings set org.gnome.settings-daemon.plugins.keyboard active false. Se anche si aggiunge una nota, cercherò di segnare vostra come la risposta (invece di quella goffa, lunga e tortuosa strada ;-)
Sadi

Questo è eccezionale. Su Ubuntu 14.04 i possibili modelli / layout / opzioni / ecc. sono elencati in/usr/share/X11/xkb/rules/evdev.lst
Jon

2
Sfortunatamente questa soluzione semplice e piacevole ha smesso di funzionare per me dopo l'aggiornamento a Ubuntu Gnome 17.04 :-(
Sadi

Ho provato Linux Mint 18.2, che si basa su Ubuntu 16.04 LTS, con udev versione 229-4ubuntu19 , nessun effetto di nuovo :-( Qualche idea su questo strano comportamento di udev ???
Sadi

2

Ho appena migliorato questa soluzione per una tastiera Typematrix bépo (versione francese di dvorak eccellente ottimizzato) e in un ampio contesto di sistema (supponiamo che tu abbia un accesso root alla macchina). Sono necessari solo 3 file per funzionare. È possibile consultare un file di registro in caso di errore per capire cosa non funziona.

/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 (assolutamente necessario per utilizzare uno script di background intermedio)

#!/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

1

Dopo aver armeggiato molto, questo è ciò che ho in esecuzione per ora. Forse scriverò un articolo completo e pubblicherò il codice all'interno di un repository, se sarebbe interessante.


Imposta una nuova serie di regole per udev in questo modo:

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

La regola dovrebbe chiamare uno script di shell ogni volta che un'azione viene attivata da un dispositivo con la combinazione data di fornitore e ID prodotto.

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

Dopo aver aggiunto il nuovo set di regole, riavviare il servizio udev:

sudo service udev restart

Nota: non sono stato in grado di ottenere risultati affidabili fornendo regole di corrispondenza più specifiche in quel file. Più significativamente, l'aggiunta di una ACTIONregola di corrispondenza non ha funzionato. Per quanto ne so, la sceneggiatura è stata attivata comunque. Quando si aggiunge ACTION=="add", lo script verrebbe comunque richiamato alla rimozione del dispositivo. Molto strano e confuso.

Tuttavia l'azione che ha attivato la regola udev sarà disponibile per lo script chiamato come mostrato di seguito.


Successivamente, la sceneggiatura stessa. Bene, non proprio. Nota il wrappersuffisso nel nome del file. Ciò indica che questo non è lo script reale ma un wrapper che chiama lo script ed esegue in background in modo che udev possa terminare il suo processo.

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

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

La variabile ACTIONcontiene l'azione udev che è stata attivata dal dispositivo. Produce valori come add(dispositivo collegato) e remove(dispositivo rimosso). Li useremo più avanti.

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

Sostituisci il mio nome utente con il tuo quando imposti la HOMEvariabile ( $(whoami)non funzionerà qui, poiché non verrà chiamato dall'utente ma da root).

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

A scopo di test, ho aggiunto alcune righe che registrano determinati eventi in un file nella mia home directory per vedere se tutto funziona. Puoi rimuoverli facilmente.


Infine, questi script devono disporre delle autorizzazioni di esecuzione. Inoltre, potrebbe essere importante notare che questi script verranno chiamati rootdall'utente, quindi fai attenzione a ciò che fai lì.

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

1
Grazie, ottimo lavoro! Ho anche funzionato. Tuttavia, il motivo per cui vedo 14 volte "Aggiungi azione" e 3 volte "Altre azioni" quando inserisco il mio comando esterno è un mistero, che proverò a risolvere in seguito. Ma ho scoperto che è meglio aggiungere anche l'ID dispositivo al comando setxkbmap in modo che la tastiera interna sia ancora utilizzabile così come la tastiera esterna, come nel mio ultimo script di avvio automatico. Ci proverò per un paio di giorni, e torno a vedere se la tua può essere considerata LA risposta, forse con una piccola modifica qua e là ;-)
Sadi

Anche ottenere le stesse linee registrate più volte. Buona cattura dell'ID dispositivo sul comando.
Kleinfreund,

@Sadi Inoltre penso che la linea gsettings set org.gnome.settings-daemon.plugins.keyboard active falsenon funzioni come previsto, poiché lo script è gestito da root. Nei miei test, la linea non ha avuto effetto su quell'impostazione.
Kleinfreund,

Penso che in uno scenario simile, potrebbe essere una buona idea eseguire il comando gsettings set org.gnome.settings-daemon.plugins.keyboard active falsecome utente una volta per tutte, quindi utilizzare questo script senza i gsettings setcomandi ...
Sadi

Finora ho visto che non possiamo ancora far funzionare questa cosa senza intoppi; di volta in volta il layout della tastiera non viene implementato da udev e devi disconnetterti e ricollegarlo. Penso che tornerò al mio script di avvio (aggiornato) nella parte superiore della mia risposta ancora per qualche tempo, il che mi serve in modo più fluido - solo devo eseguirlo manualmente se collego la mia tastiera esterna dopo l'avvio. Sembra che udev sia un po 'difettoso, come si può vedere anche in così tante ripetizioni di azione (sta eseguendo lo script wrapper molte volte e in modi strani) ...
Sadi

1

Ho avuto qualche problema di autorizzazione con lo script eseguito da udev. Ho risolto con sudo come segue:

# 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')

Imposta la mappa della tastiera per ciascun dispositivo

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

Penso che possa essere più utile se puoi scriverlo per intero. Ad esempio, dove hai messo le linee sopra?
Sadi,

0

Puoi anche definirlo in un file di configurazione di Xorg.

È strutturato in questa risposta di scambio di stack: /superuser//a/946575/437492


Sarebbe fantastico se potessi farlo funzionare. Ma usando l'ultima versione di LTS, Ubuntu 18.04, posso vedere solo la directory /usr/share/X11/xorg.conf.d/ che contiene un file chiamato 40-libinput.conf . Quindi ho semplicemente aggiunto una sezione per la tastiera esterna in quel file. Utilizzando il driver libinput o evdev e un nome fornitore più lungo e più corto, non sono riuscito a ottenere alcun risultato. Qualche idea?
Sadi,

@Sadi: se leggi un po 'sulla configurazione di Xorg, scoprirai che puoi semplicemente aggiungere nuovi file /etc/X11/xorg.conf.d/(è il posto dove andare).
Golar Ramblar,

Grazie. Ho sicuramente letto un bel po 'e ho provato prima usando "/etc/X11/xorg.conf.d/30-keyboard.conf". Proverò la mia fortuna sotto la risposta di StackExchange menzionata sopra allora. ;-)
Sadi,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.