The problem is that you probably have tested numlockx in (as it's name suggests) some X environment. X clients (GUI programs that connect to X server, e.g. Firefox or GEdit) need to know the server to connect to, and also must pass some kind of authorization. Try logging in from plain console, no matter by root or plain user, and starting some GUI application: it will show some DISPLAY related errors because it doesn't know.
To fix this you need to set environment variable DISPLAY; if you have only one X server it almost always has the address :0.
Try this at plain console: type numlockx on
, and it will show "Error opening display!". Type DISPLAY=:0 numlockx on
, and it will work (worked for me at least).
So you may set this environment variable in udev or just launch sh -c 'DISPLAY=:0 numlockx <state>'
.
I found a way to work around this, though its a little hacky.
I got to the same exact point today in trying to set up two keyboards with udev, setxkbmap, and xinput --list and for them to work with usb hotplugging. I am swapping keys around, not changing the layout, but its all the same, once you've identified your keyboard on a hotplug and can conditonally call setxkbmap, then you should be able to set the language of only the keyboard you've specified. The list of keyboard layouts can be found here ls -l /usr/share/kbd/keymaps/i386/
and you can find your device name to gre on with xinput -list
.
- You'll want to replace
rizumu
with your username, as I found it wasn't possible a way to do this without being explicit.
- Make sure you grep on the
your
keyboard name.
- Use
lsusb
to discover the Hardware ID that you need to set in the udev rule. My das keyboard looks like this Bus 002 Device 009: ID 04d9:2013 Holtek Semiconductor, Inc.
I first set up the udev rule to autodetct the keyboard is by creating a udev rule:
In the file /etc/udev/rules.d/00-usb-keyboards.rules
:
ACTION=="add", ATTRS{idVendor}=="04d9", ATTRS{idProduct}=="2013", RUN+="/home/rizumu/bin/kbd_udev", OWNER="rizumu"
I have two files ~/bin/kbd and ~/bin/kbd_udev. Make sure they have the right permissions chmod 755 ~/bin/kbd*
The ~/bin/kbd_udev
script contains:
#!/bin/bash
/home/rizumu/bin/kbd &
And you'll notice that all it does is call ~/bin/kbd
in the background, so that udev can complete its process and activate the keyboard. Inside the ~/bin/kbd
script we sleep for a second, because we need to wait until the keyboard is activated so we can get the device id using xinput. To achive this I've set some variables and exported them so xinput setxkbmap can do thier work: DISPLAY
, XAUTHORITY
, HOME
, and one daskb_id
for the id of my daskeyboard:
#!/bin/bash
sleep 1
DISPLAY=":0.0"
HOME=/home/rizumu/
XAUTHORITY=$HOME/.Xauthority
export DISPLAY XAUTHORITY HOME
daskb_id=`xinput -list | grep -i 'daskeyboard' | grep -o id=[0-9]. | grep -o [0-9]. | head -1`
xset r rate 200 30
setxkbmap -layout colemak
setxkbmap -option ctrl:nocaps
if [ "${daskb_id}" ]; then
setxkbmap -device "${daskb_id}" -option altwin:swap_lalt_lwin
fi
Best Answer
Perhaps your rule is being overwritten by another rule. Since higher numbered rules run last, it doesnt get overwritten when you use a higher number.
Check this