Sau khi loay hoay rất nhiều, đây là những gì tôi đang chạy cho bây giờ. Có lẽ tôi sẽ viết một bài viết hoàn chỉnh về các loại và xuất bản mã trong kho lưu trữ, nếu điều đó sẽ được quan tâm.
Thiết lập một quy tắc mới được đặt cho udev như thế:
sudo gedit /etc/udev/rules.d/80-external-keyboard.rules
Quy tắc được cho là gọi một tập lệnh shell bất cứ khi nào một số hành động được kích hoạt bởi một thiết bị có sự kết hợp của ID nhà cung cấp và sản phẩm.
ATTRS{idVendor}=="04b4", ATTRS{idProduct}=="4042", RUN+="/home/phil/.bin/switch-kb-layout-wrapper.sh"
Sau khi thêm bộ quy tắc mới, hãy khởi động lại dịch vụ udev:
sudo service udev restart
Lưu ý: Tôi không thể đạt được kết quả đáng tin cậy bằng cách cung cấp các quy tắc khớp cụ thể hơn trong tệp đó. Đáng kể nhất, việc thêm một ACTION
quy tắc phù hợp đã không hoạt động. Theo như tôi có thể nói, kịch bản đã được kích hoạt. Khi thêmACTION=="add"
, tập lệnh vẫn sẽ được gọi khi tháo thiết bị. Rất lạ và khó hiểu.
Tuy nhiên , hành động kích hoạt quy tắc udev sẽ có sẵn cho tập lệnh được gọi như dưới đây.
Tiếp theo, chính kịch bản. Vâng, không hoàn toàn. Lưu ý wrapper
hậu tố trong tên tập tin. Điều này chỉ ra rằng đây không phải là tập lệnh thực tế mà là một trình bao bọc gọi tập lệnh và thực thi nó trong nền để udev có thể hoàn thành quy trình của nó.
~/.bin/switch-kb-layout-wrapper.sh
:
#!/bin/sh
/home/phil/.bin/switch-kb-layout.sh "${ACTION}" &
Biến ACTION
chứa hành động udev được thiết bị kích hoạt. Nó mang lại các giá trị như add
(thiết bị đã được cắm) và remove
(thiết bị đã bị xóa). Chúng ta sẽ sử dụng chúng sau này.
~/.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
Thay thế tên người dùng của tôi bằng tên của bạn khi đặt HOME
biến ( $(whoami)
sẽ không hoạt động ở đây, vì tên này sẽ không được người dùng của bạn gọi mà bằng root
).
sed -i "s/phil/YOUR_USERNAME/g" ~/.bin/switch-kb-layout.sh
Để thử nghiệm, tôi đã thêm một số dòng ghi nhật ký một số sự kiện vào một tệp trong thư mục chính của tôi để xem mọi thứ có hoạt động không. Bạn có thể loại bỏ những thứ này.
Cuối cùng, các tập lệnh này cần phải có quyền thực thi. Ngoài ra, điều quan trọng cần lưu ý là các tập lệnh này sẽ được gọi bởi root
người dùng, vì vậy hãy cẩn thận với những gì bạn làm trong đó.
chmod +x ~/.bin/switch-kb-layout-wrapper.sh ~/.bin/switch-kb-layout.sh