Làm cách nào để gán vĩnh viễn bố cục bàn phím khác cho bàn phím USB?


16

Tôi thường cắm bàn phím USB vào máy tính xách tay của mình (ngoài màn hình và chuột bên ngoài, tất cả hầu như chuyển đổi máy tính xách tay của tôi sang máy tính để bàn) và sau đó tôi thích sử dụng bố cục bàn phím khác.

Tôi phải tự thay đổi bố cục bàn phím hiện tại mỗi lần tôi cắm bàn phím USB này.

Và tôi muốn sử dụng một cách tự động cho việc này, nếu có thể.

Câu trả lời của Radu cho câu hỏi ở đây đưa ra một số manh mối, nhưng có vẻ như tôi sẽ cần một tập lệnh khởi động cho tác vụ này vì ID thiết bị cho bàn phím USB của tôi thay đổi mỗi khi máy tính khởi động.

Tập lệnh khởi động này trước tiên có thể sẽ bao gồm lệnh xinput -list | grep "USB Keyboard"và một lệnh khác để lấy số ID Bàn phím USB đầu tiên được hiển thị và sau đó sử dụng nó trong lệnh cuối cùng để đặt bố cục đã chọn của tôi cho bàn phím USB đó như sau:

setxkbmap -device <NUMBER> -layout <LAYOUT>



1
@Sadi Bạn đang đề cập đến việc lật ngược các lá cờ của Ruthgers và US sau vụ ám sát Tiến sĩ Martin Luther King? Paul Robeson: Người tiên phong vĩ đại của Freedomways tại trang 182
khách271314

@ khách271314 Cảm ơn rất nhiều! Nhưng tôi tự hỏi tại sao bạn lại kết thúc ở đây để bình luận về câu hỏi này: history.stackexchange.com/questions/48704/ nam ;-) Đây cũng là một hình thức phản kháng thông minh khác nhưng tôi không nghĩ rằng điều này cuối cùng có thể phát triển thành tôi nghe kể chuyện.
Sadi

@Sadi Câu hỏi của bạn đã bị xóa tại Chính trị.
khách271314

Câu trả lời:


15

Sau một nghiên cứu nhỏ, tôi đã tìm thấy một giải pháp, mặc dù tôi vẫn mở cho các câu trả lời khác (có thể tốt hơn).

Đây là một tập lệnh khởi động (có thể được thêm vào Ứng dụng khởi động ), nó sẽ đặt biến usbkbd_layout được nhập nhanh chóng thành id của thiết bị usbkbd được tìm thấy trong danh sách 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

Kịch bản này khá hữu ích (và ổn định hơn) cho các tình huống khi người dùng bắt đầu sử dụng máy tính xách tay trên thiết lập máy tính để bàn (với bàn phím ngoài, chuột và màn hình, v.v.) và nó cũng có thể được chạy thủ công bất cứ khi nào cắm bàn phím USB ngoài ...

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

GIẢI PHÁP TỐT HƠN (gần như hoàn hảo) - được tìm thấy nhờ MinimusHeximus và những người đóng góp tương ứng cho chuỗi mà ông đề cập trong bình luận của mình dưới đây:

Bây giờ tôi có thể chỉ cần cắm bàn phím USB và tự động áp dụng bố cục bàn phím (TR-F) khác nhau trong khi vẫn giữ bố cục bàn phím mặc định (TR-Q) trên máy tính xách tay của mình!

Dưới đây là các tệp và nội dung của chúng làm cho điều này có thể:

/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

Ghi chú:

  1. Tất nhiên, tất cả bốn tệp trong thư mục "bin" của bạn phải có các quyền cần thiết (có thể đọc và thực thi được) có thể được triển khai ví dụ với lệnh Terminal như chmod - 755 /home/sadi/.bin/usb-keyboard-*
  2. Đôi khi, sau khi cắm bàn phím USB, nó vẫn sử dụng cùng bố cục bàn phím (mặc định) và chuyển sang bố cục đã chỉ định khi thử lần thứ hai (có lẽ cần thêm một chút thời gian ngủ ở đâu đó?)
  3. Bố cục cụ thể của bàn phím USB không hiệu quả trong màn hình đăng nhập (khi bạn Đăng xuất).
  4. Nếu bạn sử dụng một phân vùng riêng cho / home , thì có thể nên đặt bốn tập lệnh ở đâu đó trong phân vùng gốc, ví dụ / usr / local / bin và sửa đổi nội dung của tất cả các tệp tương ứng vì đôi khi udev có thể tìm kiếm những tập tin trước khi phân vùng / nhà của bạn được gắn kết và gây ra vấn đề.

ĐẶT HÀNG ĐỂ QUẢNG CÁO CÀI ĐẶT NÀY ĐỂ YÊU CẦU KHÁC BIỆT:

  1. Nhà cung cấp bàn phím USB và id sản phẩm nên được thay đổi theo đầu ra của lệnh lsusb(Ví dụ: lsusbđầu ra của tôi có cái này cho Bàn phím USB của tôi Bus 001 Device 006: ID 09da:0260 A4 Tech Co., Ltd:)
  2. Chủ sở hữu và tất cả các tên thư mục người dùng nên được thay đổi từ "sadi" sang tên khác
  3. USBkbd_id có thể yêu cầu một chút điều chỉnh để lấy id thiết bị chính xác (Ví dụ: đầu ra của các lệnh xinput -list | grep "USB Keyboard"cho tôi hai dòng; ↳ USB Keyboard id=14 [slave keyboard (3)]↳ USB Keyboard id=16 [slave keyboard (3)]sau đó được lọc bằng awkcách sử dụng "=" làm dấu phân cách trường và chụp phần thứ hai; hai chữ số đầu tiên, và sau đó chỉ sử dụng giá trị trong dòng đầu tiên)
  4. Giá trị cho usbkbd_layout có thể là bất kỳ lựa chọn hợp lệ nào khác

Sẽ thật tuyệt nếu một tập lệnh tương tự khác có thể tự động chạy bất cứ khi nào cắm bàn phím USB, như đã hỏi (chưa được trả lời) tại đây: askubfox.com/questions/284224/ Lỗi
Sadi

2
Nó có thể hữu ích nếu bạn có thể đăng câu trả lời khác ra khỏi chủ đề lộn xộn này: superuser.com/questions/249064/
Đổi

1
@MinimusHeximus Cảm ơn một triệu !!! Sau khi xem qua chuỗi mà bạn đã chỉ ra và thực hiện một số lỗi và thử, cuối cùng tôi đã sắp xếp nó và sẽ thêm giải pháp cắm nóng hoàn hảo mới (gần như) hoàn hảo ở trên!
Sadi

1
Bàn phím của tôi vì một số lý do có hai ID, vì vậy thay vì sử dụng IFtôi phải sử dụng a FOR. Nó làm việc cho tôi bây giờ, cảm ơn bạn! gist.github.com/zvictor/193b567c14b5b6a679fe
zVictor

1
@Sadi Tôi chỉ là một người dùng trung bình. Tôi sẽ đăng giải pháp của tôi ở đây. Có lẽ bạn có thể lấy một số ý tưởng về điều đó.
kleinfreund

9

Người ta có thể chỉ định các tùy chọn trình điều khiển X11 bên trong quy tắc udev, không cần tập lệnh tùy chỉnh. Ví dụ, đây là nội dung của /etc/udev/rules.d/99-usb-kbd.rules của tôi

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

Quy tắc này đảm bảo rằng một bàn phím USB cụ thể sử dụng bố cục của Hoa Kỳ trong Xorg (bàn phím bên trong máy tính xách tay của tôi là tiếng Đức và đây cũng là bố cục chính của tôi). Điểm quan trọng:

  1. Bạn có thể tìm hiểu idVendoridProductsử dụng thiết bị của mình bằng cách sử dụng lsusbhoặcevtest
  2. Bạn có thể sử dụng bất kỳ bố trí từ /usr/share/X11/xkb/symbols. Hãy chú ý chỉ định cả bố cục hợp lệ và biến thể hợp lệ.
  3. Tên tệp phải bắt đầu bằng số> 64 để cài đặt ghi đè lên cài đặt toàn hệ thống được chỉ định trong /lib/udev/rules.d/64-xorg-xkb.rules
  4. Đảm bảo rằng quản lý bố cục Gnome / KDE không ghi đè cài đặt của bạn.

Rút phích cắm và cắm lại bàn phím của bạn và xem xét /var/log/Xorg.0.logcác vấn đề có thể xảy ra. Bạn cũng có thể sử dụng udevadm infođể kiểm tra các cài đặt được áp dụng chính xác.
rốn

Eureka! Giải pháp thông minh của bạn chỉ bắt đầu hoạt động sau khi tôi nhập lệnh này (một lần cho tất cả) để ghi đè cài đặt gconf hiện tại : gsettings set org.gnome.settings-daemon.plugins.keyboard active false. Nếu bạn cũng thêm ghi chú như vậy, tôi sẽ cố gắng để đánh dấu bạn như các câu trả lời (thay vì vụng về mà, long and winding road ;-)
Sadi

Điều này là đặc biệt. Trên Ubuntu 14.04, các mô hình / bố cục / tùy chọn / vv có thể. được liệt kê tại/usr/share/X11/xkb/rules/evdev.lst
Jon

2
Thật không may, giải pháp dễ dàng và tốt đẹp này đã ngừng hoạt động đối với tôi sau khi nâng cấp lên Ubuntu Gnome 17.04 :-(
Sadi

Đã thử Linux Mint 18.2, dựa trên Ubuntu 16.04 LTS, với phiên bản udev 229-4ubfox19 , không có hiệu lực nữa :-( Mọi ý tưởng về hành vi udev kỳ quặc này ???
Sadi

2

Tôi vừa cải tiến giải pháp này cho bàn phím bépo typematrix (phiên bản tiếng Pháp của dvorak được tối ưu hóa tuyệt vời) và trong bối cảnh hệ thống rộng (nó cho rằng bạn có quyền truy cập root vào máy). Nó chỉ cần 3 tập tin để làm việc. Bạn có thể tham khảo một logfile trong trường hợp không tìm ra cái gì đang thất bại.

/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 (hoàn toàn cần thiết để sử dụng tập lệnh nền trung gian)

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

1

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 ACTIONquy 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 ý wrapperhậ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 ACTIONchứ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 HOMEbiế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 rootngườ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 

1
Cảm ơn, công việc tuyệt vời! Tôi đã có nó làm việc là tốt. Tuy nhiên, tại sao tôi thấy 14 lần "Thêm hành động" và 3 lần "Hành động khác" khi tôi bổ sung lệnh bên ngoài của mình là một bí ẩn, điều mà tôi sẽ cố gắng giải quyết sau. Nhưng tôi thấy rằng tốt hơn là thêm ID thiết bị vào lệnh setxkbmap để bàn phím bên trong vẫn có thể sử dụng được cũng như bàn phím ngoài, như trong tập lệnh tự khởi động mới nhất của tôi. Tôi sẽ thử làm điều này trong một vài ngày, và quay lại và xem liệu câu trả lời của bạn có thể được coi là câu trả lời không, có lẽ với một chút sửa đổi ở đây và đó ;-)
Sadi

Cũng nhận được cùng một dòng đăng nhập nhiều lần. Bắt tốt trên ID thiết bị trên lệnh.
kleinfreund

@Sadi Ngoài ra tôi nghĩ rằng dòng gsettings set org.gnome.settings-daemon.plugins.keyboard active falsekhông hoạt động như dự định, vì kịch bản được điều hành bởi root. Trong các thử nghiệm của tôi, dòng không có ảnh hưởng đến cài đặt đó.
kleinfreund

Tôi nghĩ trong một kịch bản như vậy, có thể nên thực hiện lệnh gsettings set org.gnome.settings-daemon.plugins.keyboard active falsenhư người dùng một lần và mãi mãi, sau đó sử dụng tập lệnh này mà không có gsettings setlệnh ...
Sadi

Cho đến nay tôi đã thấy rằng chúng ta vẫn không thể làm cho điều này hoạt động trơn tru; theo thời gian, bố cục bàn phím không được udev thực hiện và bạn phải cắm và cắm lại. Tôi nghĩ rằng tôi sẽ quay lại tập lệnh khởi động (đã cập nhật) của mình ở đầu câu trả lời của tôi một lần nữa, để phục vụ tôi trơn tru hơn - chỉ tôi phải chạy thủ công nếu tôi cắm bàn phím ngoài sau khi khởi động. Có vẻ như udev có một chút lỗi vì cũng có thể thấy trong rất nhiều lần lặp lại hành động (nó đang chạy tập lệnh bao bọc nhiều lần và theo những cách kỳ lạ) ...
Sadi

1

Tôi đã có một số vấn đề về quyền với kịch bản được thực hiện bởi udev. Tôi đã giải quyết với sudo như sau:

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

Đặt bản đồ bàn phím cho từng thiết bị

    for ID in $IDLIST; do
            sudo -u max /usr/bin/setxkbmap -device $ID -layout "${kb_layout}" -display :0
    done

Tôi nghĩ nó có thể hữu ích hơn nếu bạn có thể viết nó đầy đủ. Ví dụ, bạn đã đặt các dòng ở trên?
Sadi

0

Bạn cũng có thể định nghĩa nó trong tệp cấu hình Xorg.

Nó được đặt ra trong câu trả lời stackexchange này: /superuser//a/946575/437492


Điều đó sẽ rất tuyệt, nếu tôi có thể làm cho nó hoạt động. Nhưng bằng cách sử dụng bản phát hành LTS mới nhất, Ubuntu 18.04, tôi chỉ có thể thấy thư mục /usr/share/X11/xorg.conf.d/ có chứa một tệp có tên 40-libinput.conf . Vì vậy, tôi chỉ cần thêm một phần cho bàn phím ngoài trong tập tin đó. Sử dụng trình điều khiển libinput hoặc evdev và tên nhà cung cấp dài hơn và ngắn hơn, tôi không thể nhận được bất kỳ kết quả nào. Có ý kiến ​​gì không?
Sadi

@Sadi: Nếu bạn đọc một chút về cấu hình Xorg, bạn sẽ nhận ra rằng bạn chỉ cần thêm các tệp mới vào /etc/X11/xorg.conf.d/(đó là nơi cần đến).
Gole Ramblar

Cảm ơn. Tôi chắc chắn đã đọc khá nhiều và lần đầu tiên thử sử dụng "/etc/X11/xorg.conf.d/30-keyboard.conf". Tôi sẽ thử vận ​​may của mình dưới câu trả lời stackexchange đã đề cập ở trên. ;-)
Sadi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.