numlockx off; xdotool key Num_Lock
I like to leave NumLock on all the time but, with my current keyboard, the indicator light is a blindingly bright blue. I noticed that the numlock light would sometimes get confused, so its behaviour was reversed (only on when NumLock was turned off) but I couldn’t figure out why until now.
Here’s the deal:
First, under modern versions of X.org with MPX support, the XInput system lets you have one or more master keyboard-pointer pairs, each which can be mapped to one or more physical keyboards and mice, called slaves. (You can examine this by running
xinput in a terminal)
Here’s an example of what
xinput outputs on my system:
⎡ Virtual core pointer id=2 [master pointer (3)] ⎜ ↳ Virtual core XTEST pointer id=4 [slave pointer (2)] ⎜ ↳ ATI Remote Wonder II id=12 [slave pointer (2)] ⎜ ↳ Logitech USB Gaming Mouse id=13 [slave pointer (2)] ⎜ ↳ Wacom BambooFun 6x8 stylus id=14 [slave pointer (2)] ⎜ ↳ Wacom BambooFun 6x8 eraser id=15 [slave pointer (2)] ⎜ ↳ Wacom BambooFun 6x8 cursor id=16 [slave pointer (2)] ⎜ ↳ Wacom BambooFun 6x8 pad id=17 [slave pointer (2)] ⎣ Virtual core keyboard id=3 [master keyboard (2)] ↳ Virtual core XTEST keyboard id=5 [slave keyboard (3)] ↳ Power Button id=6 [slave keyboard (3)] ↳ Power Button id=7 [slave keyboard (3)] ↳ Guest Barcode Reader id=8 [slave keyboard (3)] ↳ CYKB23 USB Keyboard id=9 [slave keyboard (3)] ↳ CYKB23 USB Keyboard id=10 [slave keyboard (3)] ↳ zc3xx id=11 [slave keyboard (3)]
(For the curious,
zc3xx is the button on the side of my USB webcam which triggers the Logitech software under Windows by sending a keycode that maps to the
XF86WebCam keysym, same as on a multimedia keyboard)
Noteworthy implications of this design:
- It’s possible to create more masters and move devices over to them. If you do, you get extra mouse pointers on your screen and, if your window manager supports it, you can have multiple people using several different applications at the same time on the same desktop.
- Every master has a virtual slave called XTEST, which is used to inject events.
- Each slave (physical keyboard) can have its own LEDs, but the mod2 modifier that actually controls NumLock behaviour is part of the master.
- X11 doesn’t yet know how to force all the slave keyboards on a given master to share the same LED states. (Because, if you want to support all the different kinds of keyboards out there, it’s very complicated)
This means that, if you press NumLock on one keyboard, it will turn NumLock on/off for the whole master/slave grouping, but the light will only change on that one keyboard.
The problem I was having was that older versions of the
numlockx command were faking a NumLock keypress on the
XTEST virtual keyboard, rather than my physical one, and then pressing NumLock on the physical keyboard just toggled the LED and the modifier while assuming they were still in sync.
numlockx has now been fixed, but you can still trigger this mismatch manually if, like me, you want the light to come on when NumLock is turned off. Just use this command:
numlockx off; xdotool key Num_Lock
The first half puts both your NumLock modifier and LED into a known state (off) and then the call to
xdotool presses NumLock on the virtual
XTEST keyboard, which turns on the modifier and the invisible/imaginary LED on the virtual keyboard, while leaving the LED on the physical keyboard untouched.
As long as you only change your numlock state by pressing the button, they’ll stay out of sync until the end of your desktop session. Enjoy!
(Thanks to Peter Hutterer for explaining things)