После того, как я много поигрался, это то, что я бегу сейчас. Может быть, я напишу полную статью своего рода и опубликую код в репозитории, если это будет интересно.
Установите новый набор правил для 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