Kevin Kenny wrote in comp.lang.tcl on 2002-12-12:
If you own the keyboard focus, you get <Key> and <KeyRelease> events for caps lock as with any other key. When you get other keyboard and mouse events, the 'state' field in the event indicates the state of caps lock. It's a trifle platform- dependent (different platforms appear to use different state bits), but on Windows, I tried
bind all <Motion> [list updateState %s] bind all <KeyRelease-Caps_Lock> [list updateState %s] bind all <KeyRelease-Num_Lock> [list updateState %s] focus . grid [label .capslock -width 10 -textvariable capslock] grid [label .numlock -width 10 -textvariable numlock] proc updateState { s } { if { $s & 2 } { set ::capslock {CAPS LOCK} } else { set ::capslock {} } if { $s & 8 || $s & 16 } { set ::numlock {NUM LOCK} } else { set ::numlock {} } }
and it seems to give the right answers, at least when the app is on top.