Как навсегда назначить другую раскладку клавиатуры для клавиатуры USB?

16

Я часто подключаю USB-клавиатуру к своему ноутбуку (в дополнение к внешнему монитору и мыши, которые практически превращают мой ноутбук в настольный компьютер), и тогда я предпочитаю использовать другую раскладку клавиатуры.

Мне приходится вручную менять текущую раскладку клавиатуры каждый раз, когда я подключаю эту USB-клавиатуру.

И я хотел бы использовать автоматизированный способ для этого, если это возможно.

Radu ответ «S на вопрос здесь дают некоторые подсказки, но, кажется , мне нужен сценарий запуска для этой задачи , как идентификатор устройства для моего USB клавиатуры меняется каждый раз , когда компьютер начинает.

Этот сценарий запуска, вероятно, сначала будет включать команду xinput -list | grep "USB Keyboard"и другую команду, чтобы получить первый отображаемый идентификационный номер USB-клавиатуры, а затем использовать его в последней команде, чтобы установить выбранную раскладку для этой USB-клавиатуры, как показано ниже:

setxkbmap -device <NUMBER> -layout <LAYOUT>

Сади
источник
1
@Sadi Ты имеешь в виду переворачивать флаги Рутгерса и США после убийства доктора Мартина Лютера Кинга? Пол Робсон: Великий Предтеча от Freedomways на странице 182
guest271314
@ guest271314 Большое спасибо! Но мне интересно, почему вы оказались здесь, чтобы прокомментировать этот вопрос: history.stackexchange.com/questions/48704/… ;-) Это также еще одна умная форма протеста, но я не думаю, что это может в конечном итоге перерасти в Слуховая история, которую я помню.
Сади
@Sadi Ваш вопрос был удален из Политики.
guest271314

Ответы:

15

После небольшого исследования я нашел решение, хотя я все еще открыт для других (возможно, лучших) ответов.

Вот скрипт запуска (который можно добавить в автозагрузку приложений ), который установит вручную введенную переменную usbkbd_layout в идентификаторы устройства usbkbd , найденные в 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

Этот сценарий весьма полезен (и более стабилен) для сценариев, когда пользователь начинает использовать ноутбук на настольном компьютере (с внешней клавиатурой, мышью, монитором и т. Д.), И его также можно запускать вручную, когда подключена внешняя USB-клавиатура ...

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

ЛУЧШИЙ (почти идеальные) РЕШЕНИЕ - найдено благодаря MinimusHeximus и соответствующим участникам к теме он упомянул в своем комментарии ниже:

Теперь я могу просто подключить USB-клавиатуру и автоматически применить ее другую (TR-F) раскладку клавиатуры, сохраняя при этом раскладку клавиатуры по умолчанию (TR-Q) на моем ноутбуке!

Вот файлы и их содержимое, которые делают это возможным:

/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

Примечания:

  1. Конечно, все четыре файла в папке «bin» должны иметь необходимые разрешения (читаемые и исполняемые), которые могут быть реализованы, например, с помощью команды Terminal, например chmod - 755 /home/sadi/.bin/usb-keyboard-*
  2. Иногда после подключения USB-клавиатуры она по-прежнему использует ту же (по умолчанию) раскладку клавиатуры и переключается на указанную раскладку со второй попытки (возможно, потребуется немного больше времени для сна?)
  3. Специальная раскладка USB-клавиатуры не действует на экране входа в систему (при выходе из системы).
  4. Если вы используете отдельный раздел для / home , то может быть лучше поместить четыре сценария где-нибудь в корневой раздел, например / usr / local / bin, и соответственно изменить содержимое всех соответствующих файлов, как иногда может искать udev Эти файлы перед монтированием вашего / home раздела вызывают проблемы.

ДЛЯ АДАПТАЦИИ ЭТОЙ УСТАНОВКИ К РАЗЛИЧНЫМ ТРЕБОВАНИЯМ:

  1. USB клавиатуры поставщика и продукта Идентификаторы должны быть изменены в соответствии с выводом команды lsusb(например, мой lsusbвыход есть это для моего USB клавиатуры: Bus 001 Device 006: ID 09da:0260 A4 Tech Co., Ltd)
  2. ВЛАДЕЛЕЦ и все имена каталогов пользователей должны быть изменены с "sadi" на другое имя
  3. Usbkbd_id может потребоваться небольшая настройка для получения правильного идентификатора устройства (например, вывод команд xinput -list | grep "USB Keyboard"дает мне две строки; ↳ USB Keyboard id=14 [slave keyboard (3)]и ↳ USB Keyboard id=16 [slave keyboard (3)]; затем они фильтруются с awkиспользованием "=" в качестве разделителя полей и захвата второй части; затем обрезается только первые две цифры, а затем использовать только значение в первой строке)
  4. Значение для usbkbd_layout может быть любым другим допустимым выбором
Сади
источник
Было бы замечательно, если бы другой подобный скрипт мог автоматически запускаться всякий раз, когда подключена USB-клавиатура, как об этом спрашивают (пока не ответили) здесь: askubuntu.com/questions/284224/…
Sadi
2
Это может быть полезно, если вы можете опубликовать другой ответ из этой грязной темы: superuser.com/questions/249064/…
nano - объединить меня
1
@MinimusHeximus Спасибо миллион !!! Пройдя через указанную вами ветку и сделав несколько проб и ошибок, я наконец-то разобрался с ней и добавлю это новое (почти) идеальное решение для горячей замены выше!
Сади
1
Моя клавиатура по какой-то причине имеет два идентификатора, поэтому вместо использования IFмне пришлось использовать FOR. Это работает для меня сейчас, спасибо! gist.github.com/zvictor/193b567c14b5b6a679fe
zVictor
1
@Sadi Я сам обычный средний пользователь. Я опубликую свое решение здесь. Может быть, вы можете взять некоторые идеи из этого.
kleinfreund,
9

Внутри правила udev можно указать параметры драйвера X11, никаких пользовательских сценариев не требуется. В качестве примера, вот содержимое моего /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"

Это правило гарантирует, что определенная клавиатура USB использует американскую раскладку в Xorg (внутренняя клавиатура моего ноутбука - немецкая, и это также моя основная раскладка). Важные моменты:

  1. Вы можете узнать idVendorи idProductвашего устройства, используя lsusbилиevtest
  2. Вы можете использовать любой макет из /usr/share/X11/xkb/symbols. Обратите внимание, чтобы указать как верный макет, так и верный вариант.
  3. Имя файла должно начинаться с цифры> 64, чтобы настройки перезаписывали общесистемные настройки, указанные в /lib/udev/rules.d/64-xorg-xkb.rules
  4. Убедитесь, что управление макетом Gnome / KDE не перезаписывает ваши настройки.
павел
источник
Отключите и снова подключите клавиатуру и найдите /var/log/Xorg.0.logвозможные проблемы. Вы также можете использовать, udevadm infoчтобы проверить, что настройки применяются правильно.
Павел
Эврика! Ваше умное решение начал работать только после того, как я вошел в эту команду (один раз для всех) , чтобы изменить текущие настройки Gconf: gsettings set org.gnome.settings-daemon.plugins.keyboard active false. Если вы также добавите такую ​​заметку, я постараюсь отметить вашу в качестве ответа (вместо этой неуклюжей, длинной и извилистой дороги ;-)
Сади
Это исключительное. На Ubuntu 14.04 возможны модели / макеты / опции / и т.д. перечислены на/usr/share/X11/xkb/rules/evdev.lst
Jon
2
К сожалению, это красивое и простое решение перестало работать для меня после обновления до Ubuntu Gnome 17.04 :-(
Sadi
Попробовал Linux Mint 18.2, который основан на Ubuntu 16.04 LTS, с udev версии 229-4ubuntu19 , опять безрезультатно :-( Есть идеи насчет этого странного поведения udev ???
Сади
2

Я только что улучшил это решение для клавиатуры bépo Typematrix (французская версия оптимизированного превосходного дворака) и в широком системном контексте (предполагается, что у вас есть root-доступ к машине). Для работы нужно всего 3 файла. Вы можете обратиться к лог-файлу в случае невозможности выяснить, что не работает.

/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 (абсолютно необходимо использовать промежуточный фоновый скрипт)

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

/ И т.д. / 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
источник
1

После того, как я много поигрался, это то, что я бегу сейчас. Может быть, я напишу полную статью своего рода и опубликую код в репозитории, если это будет интересно.


Установите новый набор правил для udev следующим образом:

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

Правило должно вызывать сценарий оболочки всякий раз, когда какое-либо действие инициируется устройством с заданной комбинацией поставщика и идентификатора продукта.

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

После добавления нового набора правил перезапустите службу udev:

sudo service udev restart

Примечание. Мне не удалось добиться надежных результатов, предоставив более конкретные правила сопоставления в этом файле. Самое главное, что добавление ACTIONсоответствующего правила не сработало. Насколько я могу судить, сценарий был запущен в любом случае. При добавлении ACTION=="add"скрипт все равно будет вызываться при удалении устройства. Очень странно и запутанно.

Однако действие, которое вызвало правило udev, будет доступно вызываемому сценарию, как показано ниже.


Далее сам скрипт. Ну, не совсем. Обратите внимание на wrapperсуффикс в имени файла. Это указывает на то, что это не настоящий скрипт, а оболочка, которая вызывает скрипт и выполняет его в фоновом режиме, чтобы udev мог завершить свой процесс.

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

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

Переменная ACTIONсодержит действие udev, которое было запущено устройством. Он выдает такие значения, как add(устройство было подключено) и remove(устройство было удалено). Мы будем использовать их позже.

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

Замените мое имя пользователя вашим при настройке HOMEпеременной ( $(whoami)здесь не будет работать, так как он будет вызываться не вашим пользователем, а пользователем root).

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

В целях тестирования я добавил несколько строк, которые регистрируют определенные события в файле в моем домашнем каталоге, чтобы посмотреть, все ли работает. Вы можете безопасно удалить их.


Наконец, эти сценарии должны иметь разрешения на выполнение. Также может быть важно отметить, что эти сценарии будут вызываться rootпользователем, поэтому будьте осторожны с тем, что вы там делаете.

chmod +x ~/.bin/switch-kb-layout-wrapper.sh ~/.bin/switch-kb-layout.sh 
kleinfreund
источник
1
Спасибо, отличная работа! У меня это тоже работает. Однако почему я вижу 14 раз «Добавить действие» и 3 раза «Другое действие», когда подключаю свою внешнюю команду - загадка, которую я постараюсь решить позже. Но я обнаружил, что лучше добавить также идентификатор устройства в команду setxkbmap, чтобы можно было использовать как внутреннюю клавиатуру, так и внешнюю клавиатуру, как в моем последнем сценарии автозапуска. Я попробую пару дней, и вернусь и посмотрю, можно ли считать ваш ответ
Сади
Также получение одних и тех же зарегистрированных строк несколько раз. Хорошо поймал идентификатор устройства в команде.
kleinfreund
@Sadi Также я думаю, что строка gsettings set org.gnome.settings-daemon.plugins.keyboard active falseработает не так, как задумано, так как скрипт выполняется root. В моих тестах линия не влияла на эту настройку.
Kleinfreund
Я думаю, что в таком сценарии было бы неплохо выполнить команду gsettings set org.gnome.settings-daemon.plugins.keyboard active falseот имени пользователя раз и навсегда, а затем использовать этот сценарий без gsettings setкоманд ...
Сади
До сих пор я видел, что мы все еще не можем заставить эту вещь работать гладко; время от времени udev не использует раскладку клавиатуры, и вам приходится снова и снова подключаться. Я думаю, что я снова вернусь к своему (обновленному) сценарию запуска в верхней части моего ответа снова на некоторое время, что служит мне более гладко - только мне нужно запускать его вручную, если я подключаю свою внешнюю клавиатуру после запуска. Кажется, что udev немного глючит, что также можно увидеть во многих повторениях действий (он запускает скрипт-обертку много раз и странным образом) ...
Сади
1

У меня была проблема с разрешением скрипта, выполняемого udev. Я решил с sudo следующим образом:

# 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
user835020
источник
Я думаю, что это может быть более полезным, если вы можете написать это полностью. Например, где вы разместили строки выше?
Сади
0

Вы также можете определить его в конфигурационном файле Xorg.

Выложен в этом стеке обмениваться ответом: /superuser//a/946575/437492

Голар Рамблар
источник
Это было бы здорово, если бы я мог заставить это работать. Но, используя последний выпуск LTS, Ubuntu 18.04, я могу видеть только каталог /usr/share/X11/xorg.conf.d/, который содержит файл с именем 40-libinput.conf . Поэтому я просто добавил раздел для внешней клавиатуры в этом файле. Используя драйвер libinput или evdev и более длинное и короткое имя поставщика, я не смог получить никакого результата. Есть идеи?
Сади
@Sadi: Если вы немного прочтете о конфигурации Xorg, вы поймете, что можете просто добавлять новые файлы /etc/X11/xorg.conf.d/(это самое подходящее место).
Голар Рамблар
Благодарю. Я, конечно, немного прочитал и попробовал сначала использовать "/etc/X11/xorg.conf.d/30-keyboard.conf". Тогда я попробую свою удачу под ответом stackexchange, упомянутым выше. ;-)
Сади