usb klavye takılı olduğunda udev kural otomatik klavye düzeni yüklemek için


24

Bir usb klavyeyi taktığımda yeni bir klavye düzeni yüklemeye çalışıyorum ama benim udev kuralım çalışmıyor.

SUBSYSTEM == "giriş", ATTR {idVendor} == "062a", ATTR {idProduct} == "0201", GOTO = "usb_xmodmap_auto"

ETİKET = "usb_xmodmap_auto"
EYLEM == "ekle", RUN + = "/ usr / bin / xmodmap ~ / .usbXmodmap"
EYLEM == "kaldır", RUN + = "/ usr / bin / xmodmap ~ / .pndXmodmap"

Aşağıdakileri kullanarak kuralları yeniden yükledim:

> sudo udevadm kontrolü - yeniden yükleme kuralları

ve sistemi yeniden başlatarak ancak usb klavyeyi taktığımda orjinal xmodmap hala yüklendi ve bu nedenle klavye düzeni yanlış, ancak komutu terminalde çalıştırırsam

> / usr / bin / xmodmap ~ / .usbXmodmap
veya
> / usr / bin / xmodmap ~ / .pndXmodmap

Onlar sadece iyi çalışıyor.

umarım soneone yardım edebilir.

Düzenle:

Sadece daha fazla yardımcı olmak için udevadm testleri yaptım:

> udevadm testi --action = ekle /devices/platform/ehci-omap.0/usb1/1-2/1-2.3/1-2.3:1.1/input/input10

çıktılar:

run_command: calling: test
udevadm_test: sürüm 151
Bu program sadece hata ayıklama içindir, herhangi bir programı çalıştırmaz,
bir RUN tuşu ile belirtilir. Yanlış sonuçlar gösterebilir, çünkü
bazı değerler farklı olabilir veya bir simülasyon çalışmasında bulunmayabilir.

[...]
parse_file: kural dosyası olarak '/etc/udev/rules.d/usb-keyboard.rules' okunuyor
udev_rules_new: kurallar 100572 bayt jeton (8381 * 12 bayt), 21523 bayt tampon kullanır
udev_rules_new: geçici dizin kullanılmış 35380 bayt (1769 * 20 bayt)
udev_device_new_from_syspath: aygıt 0x3b4d8'de '/devices/platform/ehci-omap.0/usb1/1-2/1-2.3/1-2.3:1.1/input/input10'
udev_rules_apply_to_event: RUN '/ sbin / modprobe -b $ env {MODALIYA}' /etc/udev/rules.d/80-drivers.rules:5
udev_rules_apply_to_event: RUN 'soketi: @ / org / freedesktop / hal / udev_event' /etc/udev/rules.d/90-hal.rules:2
udev_rules_apply_to_event: RUN '/ sbin / modprobe $ env {MODALIYA}' /etc/udev/rules.d/local.rules:31
udev_rules_apply_to_event: ÇALIŞTIR 'soket: / org / çekirdek / udev / monitor' /etc/udev/rules.d/run.rules:2
udev_rules_apply_to_event: RUN '/ usr / bin / xmodmap ~ / .usbXmodmap' /etc/udev/rules.d/usb-keyboard.rules:4
udevadm_test: UDEV_LOG = 6
udevadm_test: DEVPATH = / aygıtlar / platform / ehci-omap.0 / usb1 / 1-2 / 1-2.3 / 1-2.3: 1.1 / giriş / giriş10
udevadm_test: ÜRÜN = 3 / 62a / 201/110
udevadm_test: NAME = "USB uyumlu klavye"
udevadm_test: PHYS = "usb-ehci-omap.0-2.3 / giriş1"
udevadm_test: UNIQ = ""
udevadm_test: EV == 1f
udevadm_test: KEY == 837fff 2c3027 bf004444 0 0 1fe3 c04 a27c000 267bfa d941dfed 9e0000 0 0 0
udevadm_test: REL == 143
udevadm_test: ABS == 1 0
udevadm_test: MSC == 10
udevadm_test: MODALIAS = giriş: b0003v062Ap0201e0110-e0,1,2,3,4, k71,72,73,74,77,80,82,83,85,86,87,88,89,8A, 8B, 8C, 8E, 8F, 90,96,98,9B, 9C, 9E, 9F, A1, A3, A4, A5, A6, A7, A8, A9, AB, AC, AD, AE, B1, B2, B5, CE, CF, D0, D1, D2, D5, D9, DB, E2, EA, EB, 100,101,105,106,107,108,109,10A, 10B, 10C, 162,166,16A, 16E, 178,179,17A, 17B, 17C, 17D, 17F, 180,181,182,185,18C, 18D, 192,193,195,1A0,1A1,1A2,1A3,1A4,1A5,1A6,1A7,1A8,1A9,1AA, 1AB, 1AC, 1AD, 1AE, 1B0,1B1,1B7, r0,1,6,8, a20, m4, lsfw
udevadm_test: ACTION = ekle
udevadm_test: SUBSYSTEM = giriş
udevadm_test: run: '/ sbin / modprobe -b girişi: b0003v062Ap0201e0110-e0,1,2,3,4, k71,72,73,74,77,80,82,83,85,86,87,88,89 , 8A, 8B, 8C, 8E, 8F, 90,96,98,9B, 9C, 9E, 9F, A1, A3, A4, A5, A6, A7, A8, A9, AB, AC, AD, AE, B1 B2, B5, CE, CF, D0, D1, D2, D5, D9 DB, E2, EA, EB, 100,101,105,106,107,108,109,10A, 10B, 10C, 162,166,16A, 16E, 178,179,17A, 17B, 17C, 17D , 17F, 180,181,182,185,18C, 18D, 192,193,195,1A0,1A1,1A2,1A3,1A4,1A5,1A6,1A7,1A8,1A9,1AA, 1AB, 1AC, 1AD, 1AE, 1B0,1B1,1B7, r0,1 , 6,8, a20, m4, lsfw'
udevadm_test: run: 'socket: @ / org / freedesktop / hal / udev_event'
udevadm_test: run: '/ sbin / modprobe girişi: b0003v062Ap0201e0110-e0,1,2,3,4, k71,72,73,74,77,80,82,83,85,86,87,88,89,8A , 8B, 8C, 8E, 8F, 90,96,98,9B, 9C, 9E, 9F, A1, A3, A4, A5, A6, A7, A8, A9, AB, AC, AD, AE, B1, B2 B5, CE, CF, D0, D1, D2, D5, D9 DB, E2, EA, EB, 100,101,105,106,107,108,109,10A, 10B, 10C, 162,166,16A, 16E, 178,179,17A, 17B, 17C, 17D, 17F , 180,181,182,185,18C, 18D, 192,193,195,1A0,1A1,1A2,1A3,1A4,1A5,1A6,1A7,1A8,1A9,1AA, 1AB, 1AC, 1AD, 1AE, 1B0,1B1,1B7, r0,1,6 , 8, a20, m4 lsfw'
udevadm_test: run: 'soket: / org / çekirdek / udev / monitor'
udevadm_test: run: '/ usr / bin / xmodmap ~ / .usbXmodmap'

ve

> udevadm testi --action = kaldır /devices/platform/ehci-omap.0/usb1/1-2/1-2.3/1-2.3:1.1/input/input10

çıktılar:

run_command: calling: test
udevadm_test: sürüm 151
Bu program sadece hata ayıklama içindir, herhangi bir programı çalıştırmaz,
bir RUN tuşu ile belirtilir. Yanlış sonuçlar gösterebilir, çünkü
bazı değerler farklı olabilir veya bir simülasyon çalışmasında bulunmayabilir.

[...]
parse_file: kural dosyası olarak '/etc/udev/rules.d/usb-keyboard.rules' okunuyor
udev_rules_new: kurallar 100572 bayt jeton (8381 * 12 bayt), 21523 bayt tampon kullanır
udev_rules_new: geçici dizin kullanılmış 35380 bayt (1769 * 20 bayt)
udev_device_new_from_syspath: aygıt 0x3b4d8'de '/devices/platform/ehci-omap.0/usb1/1-2/1-2.3/1-2.3:1.1/input/input10'
udev_rules_apply_to_event: RUN 'soketi: @ / org / freedesktop / hal / udev_event' /etc/udev/rules.d/90-hal.rules:2
udev_rules_apply_to_event: ÇALIŞTIR 'soket: / org / çekirdek / udev / monitor' /etc/udev/rules.d/run.rules:2
udev_rules_apply_to_event: RUN '/ usr / bin / xmodmap ~ / .pndXmodmap' /etc/udev/rules.d/usb-keyboard.rules:5
udevadm_test: UDEV_LOG = 6
udevadm_test: DEVPATH = / aygıtlar / platform / ehci-omap.0 / usb1 / 1-2 / 1-2.3 / 1-2.3: 1.1 / giriş / giriş10
udevadm_test: ÜRÜN = 3 / 62a / 201/110
udevadm_test: NAME = "USB uyumlu klavye"
udevadm_test: PHYS = "usb-ehci-omap.0-2.3 / giriş1"
udevadm_test: UNIQ = ""
udevadm_test: EV == 1f
udevadm_test: KEY == 837fff 2c3027 bf004444 0 0 1fe3 c04 a27c000 267bfa d941dfed 9e0000 0 0 0
udevadm_test: REL == 143
udevadm_test: ABS == 1 0
udevadm_test: MSC == 10
udevadm_test: MODALIAS = giriş: b0003v062Ap0201e0110-e0,1,2,3,4, k71,72,73,74,77,80,82,83,85,86,87,88,89,8A, 8B, 8C, 8E, 8F, 90,96,98,9B, 9C, 9E, 9F, A1, A3, A4, A5, A6, A7, A8, A9, AB, AC, AD, AE, B1, B2, B5, CE, CF, D0, D1, D2, D5, D9, DB, E2, EA, EB, 100,101,105,106,107,108,109,10A, 10B, 10C, 162,166,16A, 16E, 178,179,17A, 17B, 17C, 17D, 17F, 180,181,182,185,18C, 18D, 192,193,195,1A0,1A1,1A2,1A3,1A4,1A5,1A6,1A7,1A8,1A9,1AA, 1AB, 1AC, 1AD, 1AE, 1B0,1B1,1B7, r0,1,6,8, a20, m4, lsfw
udevadm_test: ACTION = kaldır
udevadm_test: SUBSYSTEM = giriş
udevadm_test: run: 'socket: @ / org / freedesktop / hal / udev_event'
udevadm_test: run: 'soket: / org / çekirdek / udev / monitor'
udevadm_test: run: '/ usr / bin / xmodmap ~ / .pndXmodmap'

çalışması gerektiğini göstermek için görünüyor, ancak bunun bir cevap almasına yardımcı olacağını ummuyor.


Yanıtlar:


16

Bu konuda çalışmanın bir yolunu buldum, ancak biraz taklit ediciydi.

Bugün udev, setxkbmap ve xinput --list ile iki klavyeyi kurmaya çalışırken ve usb hotplugging ile çalışabilmeleri için aynı noktaya geldim. Klavyenizi bir hotplug üzerinde tanımladıktan ve setxkbmap'i düzenli olarak çağırabildiğiniz ve düzenini değiştirmeden tuşları değiştiriyorum, düzeni değiştirmiyorum ama hepsi aynı. . Klavye düzenlerinin listesi burada bulunabilir ls -l /usr/share/kbd/keymaps/i386/ve cihazınızın adını gre ile bulabileceğiniz şekilde bulabilirsiniz xinput -list.

  1. rizumuAçık kullanmadan bunu yapmanın mümkün olmadığını anladığım için kullanıcı adınızla değiştirmek isteyeceksiniz .
  2. yourKlavye adını okuduğunuzdan emin olun .
  3. lsusbUudev kuralında ayarlamanız gereken Donanım Kimliğini bulmak için kullanın . Babamın klavyesi böyle görünüyorBus 002 Device 009: ID 04d9:2013 Holtek Semiconductor, Inc.

Önce udev kuralını belirledim, klavyeyi otomatik olarak tespit etmek için bir udev kuralı oluşturarak:

Dosyada /etc/udev/rules.d/00-usb-keyboards.rules:

ACTION=="add", ATTRS{idVendor}=="04d9", ATTRS{idProduct}=="2013", RUN+="/home/rizumu/bin/kbd_udev", OWNER="rizumu"

~ / Bin / kbd ve ~ / bin / kbd_udev adlı iki dosyam var. Doğru izinlere sahip olduklarından emin olunchmod 755 ~/bin/kbd*

~/bin/kbd_udevKomut içerir:

#!/bin/bash
/home/rizumu/bin/kbd &

Ve tüm ~/bin/kbdyaptıklarının arka planda çağrı olduğunu göreceksiniz , böylece udev işlemlerini tamamlayabilir ve klavyeyi etkinleştirebilir. ~/bin/kbdSenaryo içinde bir saniye uyuruz, çünkü klavyenin aktif hale gelmesini beklememiz gerekir, böylece xinput kullanarak cihaz kimliğini alabiliriz. Xinput setxkbmap dosyasını hırsız işini yapabilir yüzden bazı değişkenleri koyup bunlara ihraç ettik bunu yapabilmek için: DISPLAY, XAUTHORITY, HOME, ve bir daskb_idbenim daskeyboard ait kimliği için:

#!/bin/bash
sleep 1
DISPLAY=":0.0"
HOME=/home/rizumu/
XAUTHORITY=$HOME/.Xauthority
export DISPLAY XAUTHORITY HOME
daskb_id=`xinput -list | grep -i 'daskeyboard' | grep -o id=[0-9]. | grep -o [0-9]. | head -1`

xset r rate 200 30
setxkbmap -layout colemak
setxkbmap -option ctrl:nocaps
if [ "${daskb_id}" ]; then
    setxkbmap -device "${daskb_id}" -option altwin:swap_lalt_lwin
fi

Kendi soruma cevap vermeme yardım ettiğin için çok teşekkür ederim AskUbuntu: askubuntu.com/questions/337411/…
Sadi

Ayrıca, bu betiğin sonunda (örn. notify-send "USB Keyboard is plugged in and ready for use now." -i gtk-dialog-info -t 1000 -u normal) Bir bildirim mesajı eklememe yardımcı olabilir misiniz ? Komut dosyası oluşturma hakkında çok fazla şey bilmediğim için, "fi" den önce veya sonra eklemeyi denedim, ancak her iki durumda da bildirim mesajı tekrar tekrar görünmeye devam etti :-(
Sadi

Neden OWNERbu cihaz için ayar ?
Limbo Peng,

1
xset r rate 200 30Hat ne yapar ? xsetUbuntu 17.04 kurulumumda mevcut değil.
kleinfreund

1
xmodmap $HOME/.Xmodmap"/ Home / rizumu / bin / kbd" komutunuza benzer bir komut dosyası kullanarak çalıştıramıyorum . Bu neden olsun ki?
Geremia

5

Dağıtımınıza bağlı olarak, /lib/udev/rules.d/64-xorg-xkb.rules içindeki klavyeler için zaten bir udev kuralınız olabilir. Ubuntu’da, aşağıdaki gibi seçeneklere sahip olan / etc / default / keyboard dosyasını içe aktarır:

XKBMODEL="pc105"
XKBLAYOUT="us"
XKBVARIANT=""
XKBOPTIONS=""

Ayarlarım için, bu yerleşik kuralın özel udev kuralımdan sonra yürütüldüğünü ve ayarlarımı geçersiz kıldığını öğrendim. Bunun yerine, / etc / default / keyboard içindeki XKBOPTIONS'ı şöyle değiştirdim:

XKBOPTIONS="-option ctrl:nocaps"

"Caps Lock is Control" davranışını elde etmek için tüm klavyelerde istedim.


2
İyi fikir! Maden sadece çalışırXBKOPTIONS="ctrl:nocaps"
RasmusWL

3

GNOME kullanıyorsanız, klavye yönetim eklentisini devre dışı bırakmanız gerekir, böylece mizanpaj değişikliklerinizi geçersiz kılmaz.

gconftool-2 --toggle /apps/gnome_settings_daemon/plugins/keyboard/active

İstediğiniz gibi etkinleştirmek için aynı komutu tekrar çalıştırın.


angstrom kullanıyorum. Bu işe yarayacak mı?
Jake Aitchison

Ångström'de GNOME kullanıyor musunuz?
Ignacio Vazquez-Abrams

xfce 4.6.1 kullanarak hayır im
Jake Aitchison

1
Benim 13.04 Ubuntu'mda bu dconfaltında /org/gnome/settings-daemon/plugins/keyboard/active.
nh2

1
Ve Ubuntu 13.04'ün emri şudur:gsettings set org.gnome.settings-daemon.plugins.keyboard active false
Sadi

3

Çünkü iş yapmaz udevve xmodmapX11 ekranına erişimi yoktur. Aslında, udevorada bile bilmiyor olan aktif X11 görüntüler.

  • Not: görüntüler , çoğul. O olamaz Birden fazla olamaz çünkü "" X11 ekranı kullanabilirsiniz. Örneğin, "hızlı kullanıcı değiştirme" kullanıyorsanız.

Peki bu işi nasıl yapabilirim?
Jake Aitchison

Bunu nasıl düzeltebileceğimi bilen var mı?
Jake Aitchison

1
Setxkbmap'i çağırmak için udev aldım. Udev kuralı, başka bir komut dosyasını (yani udev'in tamamlayabilmesi için) geçmiş olan bir komut dosyasını çağırır. İkinci kod bir saniye duraklar, beklenen X11 değişkenlerini ayarlar ve setxkbmap'i tetikler. Daha fazla ayrıntı için ana soruya cevabımı görün.
Thomas Schreiber

@rizumu: Ahh, buna rağmen GDM ile çalışmak için iyi şanslar.
Grawity

3

Özel X11 kesmesi gerektirmeyen, bunu yapılandırmanın daha temiz bir yolunu bulduğumu düşünüyorum.

Bunun arkasındaki fikir udev, yalnızca yeni klavye girişini algılayacak ve her düzen için bir sembolik bağlantı oluşturacak, daha sonra inotifykullanıcı alanında yeni düzen izleyecektir.

udev kuralları

#/etc/udev/rules.d/61-usb-keyboard-layout.rules

# will match my Logitech keyboard with US layout 
SUBSYSTEM=="input", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c31c", GROUP="plugdev", MODE="0660", SYMLINK+="input/by-layout/us"

# will match my Lenovo integrated keyboard with IT layout
SUBSYSTEM=="input", ENV{ID_PATH}=="platform-i8042-serio-0", SYMLINK+="input/by-layout/it"

# force the directory to be recreated, just in case you unplug all input
SUBSYSTEM=="input", RUN="/bin/mkdir -p /dev/input/by-layout"

Bu kurallarla, /dev/input/by-layoutkullanıcı komut dosyalarındaki değişiklikleri izlemek için dev ( ) altında bir dizin var .

KDE için kullanıcı betiği

Örneğin, KDE kullanırken bu betiği (otomatik) çalıştırıyorum:

#!/bin/bash

# In case no link are found, switch to this layout
DEFAULT="it"

switch_layout () {
        [ ! -z "$1" ] || return 0
        /usr/bin/qdbus org.kde.keyboard /Layouts org.kde.KeyboardLayouts.setLayout $1
}

best_layout() {
        local LAYOUT=$(ls -1t /dev/input/by-layout/ | head -n 1)
        if [ -z "$LAYOUT" ] ; then
                LAYOUT=$DEFAULT
        fi
        echo $LAYOUT
}

switch_layout $(best_layout)

while true ; do
        EVENT=$(inotifywait -q -e create -e delete --exclude '.*tmp.*' /dev/input/by-layout/)

        if echo "$EVENT" | grep -qe CREATE ; then
                LAYOUT=${EVENT#?*CREATE }
        fi

        if echo "$EVENT" | grep -qe DELETE ; then
                LAYOUT=$(best_layout)
        fi

        switch_layout $LAYOUT
done

Bu benim için bir cazibe gibi çalışır. Sistem düzenini değiştirmek için (şu an ihtiyacım olmayan), loadkeysbir sistem init betiği kullanılarak kullanılan benzer bir komut dosyası şeytanlaştırılabilir.


Teşekkürler, bu bana , betiğin kendisi iddiasız olduğundan inotifywaitherhangi bir değişiklikte bir kurulum betiği çalıştırmak için kullanabileceğimin farkına vardı /dev/input.
Charlie Gorichanaz

3

Peki ya X.Org yapılandırması? Gönderen Gentoo Wiki: X.Org/Input_drivers - udev :

Örnek: İsviçre'nin Fransızca kısmı için bir Logitech Access klavyeniz varsa, aşağıdakileri kullanabilirsiniz:

Dosya: /etc/X11/xorg.conf.d/10-keyboard.conf

Section "InputClass"
    Identifier             "evdev keyboard catchall"
    MatchIsKeyboard        "on"
    MatchDevicePath        "/dev/input/event*"
    Driver                 "evdev"
    Option                 "XkbModel" "logiaccess"
    Option                 "XkbLayout" "ch"
    Option                 "XkbVariant" "fr"
EndSection

Ayrıntılı bir açıklama için şunu okuyun:

man xorg.conf

ve:

man evdev

ArchWiki , xorg.conf'da aynı sözdizimini kullandığını gösterir ancak "günümüzde /etc/X11/xorg.conf.d/90-keyboard-layouts.conf gibi ayrı bir yapılandırma dosyası oluşturmanız gerektiğini" belirtir. Arch'ı kullanıyorum ve mevcut /etc/X11/xorg.conf.d/vim 10-evdev.conf için çalıştığımda kendi USB klavyemi yapılandırdım.

@ rizumu: Zeki çamur, paylaşım için teşekkürler.


1
Linux Mint 18.2'de x.org.conf.d dizinine sahip değilim
Max N

2

Çalışan ekrana erişim hakkındaki sorunuzu yanıtlamak için, ekran için izinlerin doğru ayarlandığını varsayarak, komut dosyasında uygun DISPLAY değişkenini dışa aktarabilirsiniz. (man xset ekran izinleri için.)

Her zamanki gibi birçok durumda basitçe export DISPLAY=:0 gibi, tek bir kullanıcı sistemindeki ilk ekran olduğu için komut için . Doğrudan xmodmap yerine bir betiği çalıştırmak muhtemelen en kolay olanıdır çünkü ortam değişkenleri ve geri kalanı üzerinde daha fazla kontrol sahibi olmanızı sağlar. (Dolayısıyla, kuralınızdaki "/ usr / bin / xmodmap ~ / .usbXmodmap" komutunu "/usr/local/bin/keyboard_plug.sh" ile değiştirin ve uygun komutları DISPLAY değişkeni ile birlikte bu komut dosyasına koyun.)

Yukarıda da belirtildiği gibi, eğer DISPLAY =: 0 varsayarsanız, daha sonra birden fazla kullanıcı veya ekran varsa, problemlerle daha sonra karşılaşabilirsiniz. Uygun ekranı bulmak için komut dosyaları yazabilirsiniz, ancak bu durumda kendi başınızasınız (bu cevap söz konusu olduğunda). :)


1

Uudev kurallarının çalışmasını sağlamak için hack alamadığımdan, pyudevgiriş olaylarını izlemek için küçük bir Python senaryosu yazdım .

#! /usr/bin/env python3

import pyudev
import time
import subprocess

ctx = pyudev.Context()
monitor = pyudev.Monitor.from_netlink(ctx)
monitor.filter_by("input")

def defer_xmodmap():
    time.sleep(1) # not sure if there's a race here, but it feels like there could be.
    subprocess.run("xmodmap ~/dotfiles/.xmodmap", shell=True)


for device in iter(monitor.poll, None):
    # there might be a way to add the action condition to the filter, but I couldn't find it
    if device.action != "add":
        continue

    # ensure the KB is initialized -- not sure if this is actually a needed check
    if not device.is_initialized:
        continue

    # my keyboard, from the output of `lsusb`
    if not "045E:07A5" in device.device_path:
        continue

    # it's the keyboard being added.
    defer_xmodmap()

Daha sonra çalışmasını sağlamak için bu systemd kullanıcı birimi dosyasını kullanıyorum ( systemctl --user enable name_of_service_file):

[Unit]
Description=udev xmodmap monitor

[Service]
ExecStart=/usr/bin/env python3 %h/local/bin/monitor_kb_udev
Restart=always
RestartSec=10

[Install]
WantedBy=default.target

inotifywait@ Giosh94mhz gelen çözüm biraz daha basit ve bağımlılık önler pyudev. Ancak bazı nedenlerden dolayı inotify, klavyem bağlandıktan sonra etkinliğin 10-20 saniye boyunca tetiklenmediğini öğrendim .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.