I looked in the code and believe the bug is in "sdl_glimp.c". It ignores numlock and consider it all ways off.
The windows version does not use SDL, so I guess it isn't there.
So the solution is not quite obvious: Should we check for Numlock? Should we let it be? Or should it consider numlock always on?
After looking a little, I believe that the last solution is less likely to create new and more severe bugs. It is also the solution that I prefer.
RTCW, Q3A (with iD's binary), and JK II didn't use SDL and have similar behavior which kinda throws your theory out the window. Nice try though.
The behavior is just in q3 engine games, quake 2 works fine, but then the keycodes for the numpad are actually defined in src/kys.c:
void Key_Console (int key)
{
switch ( key )
{
case K_KP_SLASH:
key = '/';
break;
case K_KP_MINUS:
key = '-';
break;
case K_KP_PLUS:
key = '+';
break;
case K_KP_HOME:
key = '7';
break;
case K_KP_UPARROW:
key = '8';
break;
case K_KP_PGUP:
key = '9';
break;
case K_KP_LEFTARROW:
key = '4';
break;
case K_KP_5:
key = '5';
break;
case K_KP_RIGHTARROW:
key = '6';
break;
case K_KP_END:
key = '1';
break;
case K_KP_DOWNARROW:
key = '2';
break;
case K_KP_PGDN:
key = '3';
break;
case K_KP_INS:
key = '0';
break;
case K_KP_DEL:
key = '.';
break;
default:
break;
}
You could try inserting the above code somewhere in client/cl_keys.c to see if that fixes the issue, but then people probably won't be able to control the game with the numpad.
Aside: Doom 3 has the same behavior, but not quake 4.