Skip to content

Instantly share code, notes, and snippets.

@PofMagicfingers
Last active July 28, 2023 00:36
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save PofMagicfingers/877c9e7348d39e8891f00a2d5c462a5c to your computer and use it in GitHub Desktop.
Save PofMagicfingers/877c9e7348d39e8891f00a2d5c462a5c to your computer and use it in GitHub Desktop.
Keyboard layout auto change with udev
ATTRS{idVendor}=="060b", ATTRS{idProduct}=="5252", OWNER="pof"
ACTION=="add", RUN+="/usr/local/bin/usb-keyboard-udev in"
ACTION=="remove", RUN+="/usr/local/bin/usb-keyboard-udev out"

Keyboard auto change

Most informations and code comes from here

Installation

  • Copy the /etc/udev/rules.d/00-usb-keyboard.rules file

  • Modify idVendor, idProduct and OWNER: you can get idProduct and idVendor with lsusb

  • chmod a+x /etc/udev/rules.d/00-usb-keyboard.rules

  • Copy the /usr/local/bin/usb-keyboard-udev file

  • Copy the /usr/local/bin/usb-keyboard file

  • chmod a+x /usr/local/bin/usb-keyboard*

Modify the script /usr/local/bin/usb-keyboard :

You have to set your keyboard name in the script.

You need to get a distinctive part of your keyboard name. Just run xinput list and pick some unique part of the keyboard name.

You have to set the layout, model and variant inside the script. You can get the list of available values with these commands :

localectl list-x11-keymap-models localectl list-x11-keymap-layouts localectl list-x11-keymap-variants [layout]

For PC French Keyboard 105 keys => model: pc105, layout: fr, variant: azerty For Mac French Keyboard => model: macintosh, layout: mac-fr, variant: ""

Sidenote

For Mac keyboard, there is some custom layout on the internet, maybe worth trying : http://www.linux-france.org/macintosh/clavier_gentoo.html

cd /usr/share/kbd/keymaps/mac/all
wget ftp://ftp.linux-france.org/pub/macintosh/mac-fr-ext_new.map.gz
gunzip mac-fr-ext_new.map.gz

And use layout 'mac-fr-ext_new'

#!/bin/bash
GSETTING=/usr/bin/gsettings
SETXKBMAP=/usr/bin/setxkbmap
XINPUT=/usr/bin/xinput
KBNAME="Thermaltake"
XKBMODEL="pc105"
XKBLAYOUT="fr"
XKBVARIANT="azerty"
USERLIST=$(w -h | cut -d' ' -f1 | sort | uniq)
for CUR_USER in ${USERLIST}; do
CUR_USER_XAUTH="$(sudo -Hiu ${CUR_USER} env | grep -e "^HOME=" | cut -d'=' -f2)/.Xauthority"
CUR_USER_DISPL=":0"
export XAUTHORITY="${CUR_USER_XAUTH}"
export DISPLAY="${CUR_USER_DISPL}"
if [ -f "${CUR_USER_XAUTH}" ]; then
case $1 in
'in')
KEYBOARDS=$($XINPUT list --short | grep $KBNAME | grep keyboard | sed -e 's/^.*id=\([0-9]\+\).*/\1/g')
if [ -n "$KEYBOARDS" ]; then
[ -x $GSETTING ] && $GSETTING set org.gnome.settings-daemon.plugins.keyboard active false
for ID in $KEYBOARDS; do
[ -x $SETXKBMAP ] && $SETXKBMAP -device $ID -layout $XKBLAYOUT -model $XKBMODEL -variant $XKBVARIANT
done
notify-send "Changed $KBNAME layout to $XKBLAYOUT-$XKBVARIANT ($XKBMODEL)"
fi
echo "keyboards id(s) is (are) $KEYBOARDS"
;;
'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
fi
done
#!/bin/sh
LOG=/var/log/usb-keyboard.log
command=$(dirname $0)/usb-keyboard
echo $@ >> $LOG
[ -x "$command" ] && $command $1 >>$LOG 2>&1 &
@sapristi
Copy link

sapristi commented Dec 2, 2022

Hello,
Thanks for your script, it proved quite useful :)

However I think your udev rule

ATTRS{idVendor}=="060b", ATTRS{idProduct}=="5252", OWNER="pof"
ACTION=="add", RUN+="/usr/local/bin/usb-keyboard-udev in"
ACTION=="remove", RUN+="/usr/local/bin/usb-keyboard-udev out"

is somehow broken; at least on my distro, each line is evaluated separately, so that the first does not do anything, while the other two will match any usb device.

A fix could be

ATTRS{idVendor}=="060b", ATTRS{idProduct}=="5252", OWNER="pof", ACTION=="add", RUN+="/usr/local/bin/usb-keyboard-udev in"
ATTRS{idVendor}=="060b", ATTRS{idProduct}=="5252", OWNER="pof", ACTION=="remove", RUN+="/usr/local/bin/usb-keyboard-udev out"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment