On the history and implementation of NumLock

So, I feel it’s time for another mild rant about leaky abstractions. :slight_smile:

NumLock is a kludge. It is a kludge designed for the first IBM PC so that a directional pad and a numpad could be supported on the same limited keyboard. Its inadequacy was soon evident, so the PC/AT model M and all subsequent IBM compatible PCs have supported keyboards with separate directional and numeric keys.

To its eternal credit, Apple never implemented NumLock. To its eternal shame, Linux did.

Unfortunately, because NumLock was a software feature it had to be kept around for backwards compatibility. And then it became unkillable, to the point where modern compact keyboards that have no hard numpad (laptops, kinesis, Model01…) still have to handle NumLock.

The vast majority of PC-compatible hardware has long supported a default BIOS option “Enable NumLock on boot”, which effectively means that the user can pretend that NumLock does not exist. This appears to me to be the sensible option, and is one that is both widely supported and widely expected. On most laptop keyboards the numpad is accessed by holding down Fn. With NumLock-on-boot, this produces numbers, as it should. NumLock itself is normally hidden so well that it takes a magnifying glass to find it (on my Dell, it is Fn-F5). The only problem comes if you disable it by accident (which is why it is well hidden).

For whatever reason, the Model01 does things differently. Instead of letting the BIOS enable NumLock-on-boot and follow the practice of every other compact keyboard, it overloads the Num key and makes it toggle both the software NumLock and the firmware keypad options. When these remain in sync, nobody notices. When these fall out of sync, we have a nasty abstraction leak that renders the numpad unusable.

What is the advantage in a “smart” numlock key like this? What problem does it solve?


hehe, nasty! thanks for the heads up…

1 Like

Yeah…I ended up just replacing all the Key_Numpad* keys with Key_Num* because it seemed more straightforward - I was getting arrow keys instead of numbers, for this reason, I suppose.

1 Like

Nothing. This was a naive implementation on my part that should now be fixed in the source repo.


I was planning to just ignore NumLock altogether in my sketch. I can’t think of anything I actually need Key_Numpad* for. Does it really provide any utility at all?

Just out of curiosity, what will the new behavior be? Just a firmware toggle? If so will the Model 01 numpad functionality change if the PC is (or isn’t) in NumLock?

Thanks again for your responsiveness on all these little issues. I sometimes feel like we are pretty demanding crowd, but you handle everything and everyone with such grace!


I do a good amount of number entry (spreadsheets and accounting and all that fun stuff). Not having a number pad makes some tasks a lot slower. I’m appreciative of the effort to include that functionality in the keyboard, but I may end up with a standalone number pad unit, personally.

The thing that @algernon put together most recently is for us to be aware of and honor the PC’s numlock state. I need to play with the design a little bit to decide how we’re going to expose Numlock vs the numpad layer toggle.

The thing is, with a programmable keyboard, you can have a number pad without needing the keycodes for the number pad. I’m contemplating having a layout where the numbers are only available on a “numpad” layer, but those numbers are Key_8 (for example), not Key_Keypad8. I’m not aware of any need for the latter, and the former are unaffected by the host’s NumLock state.


I get what you’re saying now. In other words, what’s the point of sending the keypad codes vs. just the regular number codes on the numpad layer. Agreed - probably not much point.

They aren’t affected by NumLock, but they are affected by OS keymap. For example, azerty uses them for accented letters and punctuation. Programmer-Dvorak uses them for brackets and symbols. And Hungarian zero is not where you think it is.


I’m trying to document the way keymaps work, and thinking about how to explain the magic Key_KeypadNumLock. It would make a lot more sense if it were LockLayer(NUMPAD). I had forgotten that it wasn’t defined that way.

It…may be that way again in the not too distant future.

1 Like

:slight_smile: If you change it poke me to revise the docs. :slight_smile:

As a side note, I’m adding the things that are called out in the default .ino as needing documentation to the wiki intro, so a lot of that comment block could be replaced with a link. I don’t know when you are pushing a revision to Arduino, but please let’s get that revised before it goes live.

1 Like

This definitely isn’t the most serious of needs, but in heavily modded Minecraft one can quickly run out of mappable keys. The fact that the keypad keycodes are distinct from the keycodes for the “regular” numbers is taken for granted in the default key mappings used by some of the mods.

For those not familiar with Minecraft, you have a hotbar with nine slots, with the “regular” numbers 1-9 switching your active item to the one in that slot.

Because Key_Numpad0 is distinct from Key_0 it can be assigned something different. (disclaimer, I’m fairly certain that those aren’t the correct keycode names).

I’m undecided whether this is an argument in favor of things NumLock or an example of just how badly misused the feature has become. Maybe both.

I think this means that we probably ought to keep these Key_Numpad* codes mapped in the default firmware.

This is something I still haven’t figured out how I’m going to address when I build my own layout.

All true, but irrelevant to the question of whether the keycodes for the keys on the numeric keypad are actually useful for anything.

This was the kind of thing I was guessing. Can’t you assign those functions to letter keys, though?

Under Windows, alt+numpad gives you arbitrary Unicode codepoints. Alt+number row does not.


They are useful when you want to type a number in a way that is keymap independent. If you were to assign number row scancodes to the keypad numbers, it would only work the way you expect some of the time.

They’re also useful if you want to end up with the non Numlock variants of those keys.

Mostly, we wanted to use those keys because there are random odd things that depend on the exact HID key events for numpad keys and we’d be happier not to break things.

If we hadn’t sorted out the system numlock toggle problem, my plan was to use the non-numpad versions of the keys as a stopgap.