Bagaimana cara menetapkan tata letak keyboard yang berbeda secara permanen ke keyboard USB?

16

Saya sering memasang keyboard USB ke laptop saya (selain monitor eksternal dan mouse, yang semuanya mengubah laptop saya menjadi komputer desktop) dan saya lebih suka menggunakan tata letak keyboard yang berbeda.

Saya harus mengubah tata letak keyboard saat ini secara manual setiap kali saya memasang keyboard USB ini.

Dan saya ingin menggunakan cara otomatis untuk ini, jika memungkinkan.

Jawaban Radu untuk pertanyaan di sini memberikan beberapa petunjuk, tetapi sepertinya saya akan memerlukan skrip startup untuk tugas ini karena ID perangkat untuk keyboard USB saya berubah setiap kali komputer dinyalakan.

Skrip startup ini mungkin pertama kali akan menyertakan perintah xinput -list | grep "USB Keyboard", dan perintah lain untuk mengambil nomor ID Keyboard USB pertama yang ditampilkan dan kemudian menggunakannya dalam perintah terakhir untuk mengatur tata letak yang saya pilih untuk keyboard USB itu seperti di bawah ini:

setxkbmap -device <NUMBER> -layout <LAYOUT>

Sadi
sumber
1
@Sadi Apakah Anda merujuk membalik Rutgers dan bendera AS setelah pembunuhan Dr. Martin Luther King? Paul Robeson: The Great Forerunner oleh Freedomways di halaman 182
tamu271314
@ guest271314 Terima kasih banyak! Tapi saya bertanya-tanya bagaimana Anda bisa berakhir di sini untuk mengomentari pertanyaan ini: history.stackexchange.com/questions/48704/... ;-) Ini juga bentuk protes yang cerdas, tetapi saya tidak berpikir bahwa ini akhirnya bisa berkembang menjadi cerita desas-desus yang saya ingat.
Sadi
@Sadi Pertanyaan Anda telah dihapus di Politik.
guest271314

Jawaban:

15

Setelah sedikit riset, saya telah menemukan solusi, meskipun saya masih terbuka untuk jawaban lain (mungkin lebih baik).

Berikut ini skrip startup (yang dapat ditambahkan ke Aplikasi Startup ) yang akan mengatur variabel usbkbd_layout yang dimasukkan secara otomatis ke perangkat id perangkat usbkbd yang ditemukan dalam daftar 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

Skrip ini cukup berguna (dan lebih stabil) untuk skenario di mana pengguna mulai menggunakan laptop pada pengaturan desktop (dengan keyboard eksternal, mouse dan monitor, dll.), Dan juga dapat dijalankan secara manual setiap kali keyboard USB eksternal dipasang ...

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

SOLUSI YANG LEBIH BAIK (hampir sempurna) - ditemukan berkat MinimusHeximus dan masing-masing kontributor pada utas yang ia sebutkan dalam komentarnya di bawah:

Saya sekarang bisa saja meng-plugin keyboard USB saya dan secara otomatis menerapkan tata letak keyboard (TR-F) yang berbeda sambil tetap mempertahankan tata letak keyboard default (TR-Q) di laptop saya!

Berikut adalah file dan isinya yang memungkinkan ini:

/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

Catatan:

  1. Tentu saja keempat file di folder "bin" Anda harus memiliki izin yang diperlukan (dapat dibaca dan dieksekusi) yang mungkin diimplementasikan misalnya dengan perintah Terminal seperti chmod - 755 /home/sadi/.bin/usb-keyboard-*
  2. Kadang-kadang setelah keyboard USB terpasang, masih menggunakan tata letak keyboard (default) yang sama, dan beralih ke tata letak yang ditentukan pada percobaan kedua (mungkin memerlukan sedikit waktu tidur di suatu tempat?)
  3. Tata letak khusus keyboard USB tidak efektif di layar masuk (saat Anda Keluar).
  4. Jika Anda menggunakan partisi terpisah untuk / home , maka mungkin ide yang lebih baik untuk meletakkan empat skrip di suatu tempat di partisi root, misalnya / usr / local / bin dan memodifikasi isi semua file masing-masing sesuai kadang-kadang udev mencari file-file tersebut sebelum partisi / home Anda di -mount dan menyebabkan masalah.

UNTUK MENYESUAIKAN SETUP INI UNTUK PERSYARATAN YANG BERBEDA:

  1. Keyboard USB penjual dan produk id harus diubah sesuai dengan output dari perintah lsusb(Misalnya, saya lsusbkeluaran memiliki ini untuk Keyboard USB saya: Bus 001 Device 006: ID 09da:0260 A4 Tech Co., Ltd)
  2. PEMILIK dan semua nama direktori pengguna harus diubah dari "sadi" ke nama lain
  3. The usbkbd_id mungkin memerlukan sedikit penyesuaian untuk mengambil id perangkat yang benar (Misalnya, output dari perintah xinput -list | grep "USB Keyboard"memberi saya dua baris; ↳ USB Keyboard id=14 [slave keyboard (3)]dan ↳ USB Keyboard id=16 [slave keyboard (3)]; yang kemudian disaring dengan awkmenggunakan "=" sebagai pembatas bidang dan menangkap bagian kedua; kemudian memotong hanya dua digit pertama, dan kemudian hanya menggunakan nilai di baris pertama)
  4. Nilai untuk usbkbd_layout mungkin merupakan pilihan lain yang valid
Sadi
sumber
Alangkah baiknya
Sadi
2
Akan sangat membantu jika Anda dapat mengirim jawaban lain dari utas yang berantakan ini: superuser.com/questions/249064/…
nano - gabungkan saya
1
@MinimusHeximus Terima kasih banyak !!! Setelah melalui utas yang telah Anda tunjukkan dan coba-coba, saya akhirnya menyortirnya dan akan menambahkan solusi hotplugging sempurna (hampir) sempurna ini di atas!
Sadi
1
Keyboard saya karena beberapa alasan memiliki dua ID, jadi alih-alih menggunakan, IFsaya harus menggunakan a FOR. Ini bekerja untuk saya sekarang, terima kasih! gist.github.com/zvictor/193b567c14b5b6a679fe
zVictor
1
@Sadi Saya hanyalah pengguna biasa. Saya akan memposting solusi saya di sini. Mungkin Anda bisa mengambil beberapa ide dari itu.
kleinfreund
9

Orang dapat menentukan opsi driver X11 di dalam aturan udev, tidak ada skrip khusus yang diperlukan. Sebagai contoh, berikut adalah isi dari /etc/udev/rules.d/99-usb-kbd.rules saya

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

Aturan ini memastikan bahwa keyboard USB tertentu menggunakan tata letak AS di Xorg (keyboard internal laptop saya adalah bahasa Jerman, dan ini juga tata letak utama saya). Poin-poin penting:

  1. Anda dapat menemukan idVendordan idProductperangkat Anda menggunakan lsusbatauevtest
  2. Anda dapat menggunakan tata letak apa pun dari /usr/share/X11/xkb/symbols. Perhatikan untuk menentukan tata letak yang valid dan varian yang valid.
  3. Nama file harus dimulai dengan angka> 64 agar pengaturan untuk menimpa pengaturan sistem yang ditentukan dalam /lib/udev/rules.d/64-xorg-xkb.rules
  4. Pastikan bahwa manajemen tata letak Gnome / KDE tidak menimpa pengaturan Anda.
pavel
sumber
Cabut dan pasang kembali keyboard Anda dan cari /var/log/Xorg.0.logkemungkinan masalah. Anda juga dapat menggunakan udevadm infountuk memeriksa apakah pengaturan diterapkan dengan benar.
pavel
Eureka! Solusi cerdas Anda mulai bekerja hanya setelah saya masuk perintah ini (sekali untuk semua) untuk mengesampingkan pengaturan gconf saat ini: gsettings set org.gnome.settings-daemon.plugins.keyboard active false. Jika Anda juga menambahkan catatan seperti itu, saya akan mencoba untuk menandai Anda sebagai yang jawaban (bukan canggung itu, panjang dan berkelok-kelok jalan ;-)
Sadi
Ini luar biasa. Pada Ubuntu 14.04 kemungkinan model / tata letak / opsi / dll. terdaftar di/usr/share/X11/xkb/rules/evdev.lst
Jon
2
Sayangnya solusi yang bagus dan mudah ini berhenti bekerja untuk saya setelah memutakhirkan ke Ubuntu Gnome 17.04 :-(
Sadi
Mencoba Linux Mint 18.2, yang didasarkan pada Ubuntu 16.04 LTS, dengan udev versi 229-4ubuntu19 , tidak ada efek lagi :-( Ada gagasan tentang perilaku udev yang aneh ini ???
Sadi
2

Saya baru saja meningkatkan solusi ini untuk keyboard Typematrix bépo (versi perancis dari dvorak yang sangat baik dioptimalkan) dan dalam konteks sistem yang luas (itu mengandaikan bahwa Anda memiliki akses root ke mesin). Hanya perlu 3 file untuk bekerja. Anda dapat berkonsultasi dengan file log jika gagal untuk mencari tahu apa yang gagal.

/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 (benar-benar diperlukan untuk menggunakan skrip latar belakang menengah)

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

Setelah banyak mengutak-atik, inilah yang saya jalankan sekarang. Mungkin saya akan menulis artikel yang lengkap dan menerbitkan kode dalam repositori, jika itu menarik.


Siapkan aturan baru yang ditetapkan untuk udev seperti itu:

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

Aturan seharusnya memanggil skrip shell setiap kali beberapa tindakan dipicu oleh perangkat dengan kombinasi yang diberikan vendor dan ID produk.

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

Setelah menambahkan set aturan baru, restart layanan udev:

sudo service udev restart

Catatan: Saya tidak dapat mencapai hasil yang dapat diandalkan dengan memberikan aturan pencocokan yang lebih spesifik dalam file itu. Paling signifikan, menambahkan ACTIONaturan yang cocok tidak berhasil. Sejauh yang saya tahu, skrip itu dipicu pula. Saat menambahkan ACTION=="add", skrip masih akan dipanggil saat melepas perangkat. Sangat aneh dan membingungkan.

Namun tindakan yang memicu aturan udev akan tersedia untuk skrip yang dipanggil seperti yang ditunjukkan di bawah ini.


Selanjutnya, skrip itu sendiri. Ya tidak cukup. Perhatikan wrapperakhiran dalam nama file. Ini menunjukkan bahwa ini bukan skrip aktual tetapi pembungkus yang memanggil skrip dan menjalankannya di latar belakang sehingga udev dapat menyelesaikan prosesnya.

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

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

Variabel ACTIONberisi tindakan udev yang dipicu oleh perangkat. Ini menghasilkan nilai seperti add(perangkat dicolokkan) dan remove(perangkat dihapus). Kami akan menggunakannya nanti.

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

Ganti nama pengguna saya dengan milik Anda saat mengatur HOMEvariabel ( $(whoami)tidak akan berfungsi di sini, karena ini tidak akan dipanggil oleh pengguna Anda tetapi oleh root).

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

Untuk tujuan pengujian, saya menambahkan beberapa baris yang mencatat peristiwa tertentu ke file di direktori home saya untuk melihat apakah semuanya berfungsi. Anda dapat menghapus ini dengan hemat.


Akhirnya, skrip ini harus memiliki izin eksekusi. Mungkin juga penting untuk dicatat bahwa skrip ini akan dipanggil oleh rootpengguna, jadi berhati-hatilah dengan apa yang Anda lakukan di sana.

chmod +x ~/.bin/switch-kb-layout-wrapper.sh ~/.bin/switch-kb-layout.sh 
kleinfreund
sumber
1
Terima kasih, kerja bagus! Saya sudah membuatnya bekerja juga. Namun, mengapa saya melihat 14 kali "Tambahkan tindakan" dan 3 kali "Tindakan lainnya" ketika saya memasang perintah eksternal saya adalah sebuah misteri, yang akan saya coba selesaikan nanti. Tetapi saya telah menemukan bahwa lebih baik untuk menambahkan juga ID perangkat ke perintah setxkbmap sehingga keyboard internal masih dapat digunakan serta keyboard eksternal, seperti dalam skrip autostartup terbaru saya. Saya akan mencoba ini selama beberapa hari, dan kembali dan melihat apakah jawaban Anda dapat dianggap sebagai jawaban, mungkin dengan sedikit modifikasi di sana-sini ;-)
Sadi
Juga mendapatkan baris yang sama berulang kali. Bagus menangkap ID perangkat pada perintah.
kleinfreund
@Sadi Juga saya pikir baris gsettings set org.gnome.settings-daemon.plugins.keyboard active falsetidak berfungsi sebagaimana dimaksud, karena skrip dijalankan oleh root. Dalam pengujian saya, saluran tidak berpengaruh pada pengaturan itu.
kleinfreund
Saya pikir dalam skenario seperti itu, mungkin ide yang baik untuk menjalankan perintah gsettings set org.gnome.settings-daemon.plugins.keyboard active falsesebagai pengguna sekali dan untuk semua, dan kemudian menggunakan skrip ini tanpa gsettings setperintah ...
Sadi
Sejauh ini saya telah melihat bahwa kita masih tidak bisa membuat benda ini bekerja dengan lancar; dari waktu ke waktu tata letak keyboard tidak diimplementasikan oleh udev, dan Anda harus mematikan dan menyambungkan lagi. Saya pikir saya akan kembali ke skrip startup saya (yang diperbarui) di bagian atas jawaban saya lagi untuk beberapa waktu, yang membuat saya lebih lancar - hanya saya harus menjalankannya secara manual jika saya mencolokkan keyboard eksternal saya setelah startup. Tampaknya udev agak buggy karena juga dapat dilihat dalam begitu banyak pengulangan tindakan (itu menjalankan skrip pembungkus berkali-kali, dan dengan cara yang aneh) ...
Sadi
1

Saya punya masalah izin dengan skrip yang dijalankan oleh udev. Saya memutuskan dengan sudo sebagai berikut:

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

Atur peta keyboard untuk setiap perangkat

    for ID in $IDLIST; do
            sudo -u max /usr/bin/setxkbmap -device $ID -layout "${kb_layout}" -display :0
    done
pengguna835020
sumber
Saya pikir itu bisa lebih berguna jika Anda dapat menulisnya secara penuh. Misalnya, di mana Anda meletakkan garis di atas?
Sadi
0

Anda juga dapat mendefinisikannya dalam file konfigurasi Xorg.

Itu diletakkan dalam jawaban stackexchange ini: /superuser//a/946575/437492

Ramblar Golar
sumber
Itu akan bagus, jika saya bisa membuatnya bekerja. Tetapi menggunakan rilis LTS terbaru, Ubuntu 18.04, saya hanya bisa melihat direktori /usr/share/X11/xorg.conf.d/ yang berisi file bernama 40-libinput.conf . Jadi saya hanya menambahkan bagian untuk keyboard eksternal dalam file itu. Menggunakan libinput driver atau evdev dan nama vendor yang lebih panjang dan lebih pendek, saya tidak bisa mendapatkan hasil apa pun. Ada ide?
Sadi
@Sadi: Jika Anda membaca sedikit tentang konfigurasi Xorg, Anda akan mengetahui bahwa Anda dapat menambahkan file baru ke /etc/X11/xorg.conf.d/(itu adalah tempat untuk pergi).
Golar Ramblar
Terima kasih. Saya pasti membaca sedikit dan mencoba dulu menggunakan "/etc/X11/xorg.conf.d/30-keyboard.conf". Saya akan mencoba keberuntungan saya di bawah jawaban stackexchange yang disebutkan di atas. ;-)
Sadi